2015-10-14 18 views
13


sto attualmente costruendo un'applicazione di targeting API 23, con un minimo API di 19.
In API 23 alcuni dei metodi del componente android.widget.TimePicker stato sostituito.
trattati i metodi deprecati in androide

Ad esempio:

TimePicker.getCurrentHour(); 

è stato sostituito da:

TimePicker.getHour(); 

Ora, quando si utilizza TimePicker nella mia app dovrei verificare se il dispositivo utilizza API 22 o superiore con la seguente, se dichiarazione:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
     TimePicker.getHour(); 
    else 
     TimePicker.getCurrentHour(); 

Quello che ho fatto è stato estendere la classe TimePicker e impl ementing i metodi deprecati in questo modo:

public class TimePicker extends android.widget.TimePicker { 

    public TimePicker(Context context) { 
     super(context); 
    } 

    public void setCurrentHour(int hour) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
      super.setHour(hour); 
     else 
      super.setCurrentHour(hour); 
    } 

    public void setCurrentMinute(int minute) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
      super.setMinute(minute); 
     else 
      super.setCurrentMinute(minute); 
    } 

    public int getCurrentHour() { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
      return super.getHour(); 
     else 
      return super.getCurrentHour(); 
    } 

    public int getCurrentMinute() { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
      return super.getMinute(); 
     else 
      return super.getCurrentMinute(); 
    } 
} 

quindi l'utente che utilizza questa classe non influenzerà il cambiamento dei metodi (che dovrebbe sostituire solo l'importazione della classe TimePicker nella sua attuazione).

È il modo giusto di farlo? o c'è una soluzione migliore?

Grazie

+2

E 'un buon modo. Secondo me, l'hai inchiodato! :) Forse i tuoi metodi dovrebbero essere nominati dopo la nuova convenzione sui nomi, rendendo più facile la transizione quando si rilascia il supporto per la pre M. – Kenneth

+0

hey, Di cosa si tratta .M? –

+0

Build.VERSION_CODES.M si riferisce all'API 23 (Android Marshmallow) –

risposta

3

Il modo in cui è stata eseguita è buona prassi per quanto posso leggere dalla parte indicata.

Tuttavia, come ho visto finora, la procedura migliore è stata quella di creare suddivisioni diverse da ogni classe che si intende pubblicare e impilare il programma durante l'installazione.

Ciò significa in pratica che if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) è in cima alla classe.

Se il progetto si propone di andare sotto più versioni, suggerisco questo:

public class Example extends moreExamples implements additionalExamples{ 
    switch(Build.VERSION.SDK_INT){ 
     case Build.VERSION_CODES.M: 
     codeVersionM(); 
     break; 
     case Build.VERSION_CODES.L: 
     codeVersionL(); 
     break; 
     case Build.VERSION_CODES.K: 
     codeVersionK(); 
     break; 
     default: 
     errorNoBuildImplemented(); 
    } 
} 
1

E 'meglio utilizzare le nuove nomi di metodo. In questo modo è possibile eliminare la classe di compatibilità quando si alza la versione min sdk a 23, senza dover modificare alcun codice diverso dalle importazioni.

@SuppressWarnings("deprecation") 
public class TimePicker extends android.widget.TimePicker 
{ 
    public TimePicker(Context context) 
    { 
     super(context); 
    } 

    public TimePicker(Context context, AttributeSet attrs) 
    { 
     super(context, attrs); 
    } 

    public TimePicker(Context context, AttributeSet attrs, int defStyleAttr) 
    { 
     super(context, attrs, defStyleAttr); 
    } 

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 
    public TimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) 
    { 
     super(context, attrs, defStyleAttr, defStyleRes); 
    } 

    public void setHour(int hour) 
    { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
      super.setHour(hour); 
     else 
      super.setCurrentHour(hour); 
    } 

    public void setMinute(int minute) 
    { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
      super.setMinute(minute); 
     else 
      super.setCurrentMinute(minute); 
    } 

    public int getHour() 
    { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
      return super.getHour(); 
     else 
      return super.getCurrentHour(); 
    } 

    public int getMinute() 
    { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
      return super.getMinute(); 
     else 
      return super.getCurrentMinute(); 
    } 
} 
3

Quello che hai fatto è discreta, ma probabilmente non è la soluzione migliore perché:

  • Si utilizza i vecchi nomi dei metodi, invece di quelle nuove
  • Creazione di una delle forze di classe personalizzati da utilizzare per quel classe personalizzata nei tuoi layout e codice in sostituzione della classe del framework. È preferibile evitare di creare visualizzazioni personalizzate, se possibile.

Ci sono generalmente due modi: raccomandato

1) continuare ad usare il metodo deprecato fino a quando si aggiorna il minSDK.Si chiamerà il nuovo metodo internamente la nuova implementazione:

@Deprecated 
public void setCurrentHour(@NonNull Integer currentHour) { 
    setHour(currentHour); 
} 

2) Creare una classe di supporto statica che chiamerà il metodo corretto in base alla versione SDK. Questo è ciò che la libreria di supporto fa per molte classi già (TextViewCompat, ViewCompat, ...):

public class TimePickerCompat { 

    public static void setHour(TimePicker timePicker, int hour) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
      timePicker.setHour(hour); 
     } else { 
      timePicker.setCurrentHour(hour); 
     } 
    } 

}