Questa lezione spiega come creare un'implementazione che rispecchi le API più recenti, ma supporti i dispositivi meno recenti.
Scegli una soluzione sostitutiva
Il compito più difficile nell'utilizzo delle funzionalità dell'interfaccia utente più recenti in modo compatibile con le versioni precedenti è decidere e implementare una soluzione precedente (di riserva) per le versioni precedenti della piattaforma. In molti casi, è possibile soddisfare le finalità di questi nuovi componenti dell'interfaccia utente utilizzando funzionalità meno recenti del framework dell'interfaccia utente. Ad esempio:
-
Le barre di azioni possono essere implementate utilizzando un
LinearLayout
orizzontale contenente pulsanti di immagine, come barre dei titoli personalizzate o come visualizzazioni nel layout dell'attività. Le azioni di overflow possono essere visualizzate sotto il pulsante Menu del dispositivo. -
Le schede della barra delle app possono essere implementate utilizzando un
LinearLayout
orizzontale contenente pulsanti o l'elementoTabWidget
dell'interfaccia utente. -
I widget
NumberPicker
eSwitch
possono essere implementati utilizzando rispettivamente i widgetSpinner
eToggleButton
. -
I widget
ListPopupWindow
ePopupMenu
possono essere implementati utilizzando i widgetPopupWindow
.
In genere, non esiste una soluzione universale per il backporting dei componenti dell'interfaccia utente più recenti ai dispositivi meno recenti. Presta attenzione all'esperienza utente: sui dispositivi meno recenti, gli utenti potrebbero non avere familiarità con i più recenti pattern di progettazione e componenti dell'interfaccia utente. Valuta la possibilità di offrire la stessa funzionalità utilizzando elementi familiari. In molti casi, questo non è un problema, ad esempio se i componenti dell'interfaccia utente più recenti sono in evidenza nell'ecosistema dell'applicazione (come la barra delle app) o se il modello di interazione è estremamente semplice e intuitivo (come le visualizzazioni con scorrimento utilizzando un ViewPager
).
Implementare le schede utilizzando API precedenti
Per creare un'implementazione precedente delle schede della barra delle azioni, puoi utilizzare TabWidget
e TabHost
(anche se in alternativa è possibile utilizzare widget Button
disposti in orizzontale). Implementa questa funzionalità nelle classi TabHelperEclair
e CompatTabEclair
, poiché questa implementazione utilizza API introdotte non oltre Android 2.0 (Eclair).

Figura 1. Diagramma di classi per l'implementazione delle schede in Eclair.
L'implementazione di CompatTabEclair
memorizza le proprietà delle schede, come il testo e l'icona, nelle variabili di istanza, poiché non è disponibile un oggetto ActionBar.Tab
per gestire questo spazio di archiviazione:
class CompatTabEclair internal constructor(val activity: FragmentActivity, tag: String) :
CompatTab(tag) {
// Store these properties in the instance,
// as there is no ActionBar.Tab object.
private var text: CharSequence? = null
...
override fun setText(resId: Int): CompatTab {
// Our older implementation simply stores this
// information in the object instance.
text = activity.resources.getText(resId)
return this
}
...
// Do the same for other properties (icon, callback, etc.)
}
public class CompatTabEclair extends CompatTab {
// Store these properties in the instance,
// as there is no ActionBar.Tab object.
private CharSequence text;
...
public CompatTab setText(int resId) {
// Our older implementation simply stores this
// information in the object instance.
text = activity.getResources().getText(resId);
return this;
}
...
// Do the same for other properties (icon, callback, etc.)
}
L'implementazione di TabHelperEclair
utilizza i metodi del widget TabHost
per creare oggetti TabHost.TabSpec
e indicatori di scheda:
class TabHelperEclair internal constructor(activity: FragmentActivity) : TabHelper(activity) {
private var tabHost: TabHost? = null
...
override fun setUp() {
// Our activity layout for pre-Honeycomb devices
// must contain a TabHost.
tabHost = tabHost ?: mActivity.findViewById<TabHost>(android.R.id.tabhost).apply {
setup()
}
}
override fun addTab(tab: CompatTab) {
...
tabHost?.newTabSpec(tab.tag)?.run {
setIndicator(tab.getText()) // And optional icon
...
tabHost?.addTab(this)
}
}
// The other important method, newTab() is part of
// the base implementation.
}
public class TabHelperEclair extends TabHelper {
private TabHost tabHost;
...
protected void setUp() {
if (tabHost == null) {
// Our activity layout for pre-Honeycomb devices
// must contain a TabHost.
tabHost = (TabHost) mActivity.findViewById(
android.R.id.tabhost);
tabHost.setup();
}
}
public void addTab(CompatTab tab) {
...
TabSpec spec = tabHost
.newTabSpec(tag)
.setIndicator(tab.getText()); // And optional icon
...
tabHost.addTab(spec);
}
// The other important method, newTab() is part of
// the base implementation.
}
Ora hai due implementazioni di CompatTab
e TabHelper
: una che funziona su dispositivi con Android 3.0 o versioni successive e che utilizza nuove API, e un'altra che funziona su dispositivi con Android 2.0 o versioni successive che utilizza API meno recenti. Nella prossima lezione parleremo dell'utilizzo di queste implementazioni nella tua applicazione.