Crea un'implementazione con API precedenti

Questa lezione spiega come creare un'implementazione che rispecchia le API più recenti, ma supporta i dispositivi meno recenti.

Scegliere una soluzione sostitutiva

L'attività più impegnativa nell'utilizzo delle funzionalità della UI più recenti in modo retrocompatibile è la scelta e l'implementazione di una soluzione precedente (di riserva) per le versioni precedenti della piattaforma. In molti casi, è possibile soddisfare lo scopo di questi componenti della UI più recenti utilizzando le funzionalità del framework della UI precedenti. Ad esempio:

  • Le barre delle azioni possono essere implementate utilizzando un LinearLayout orizzontale contenente pulsanti immagine, come barre del titolo personalizzate o come visualizzazioni nel layout dell'attività. Le azioni di overflow possono essere presentate sotto il pulsante Menu del dispositivo.

  • Le schede della barra delle azioni possono essere implementate utilizzando un LinearLayout orizzontale contenente pulsanti o l'elemento UI TabWidget.

  • I widget NumberPicker e Switch possono essere implementati utilizzando rispettivamente i widget Spinner e ToggleButton.

  • I widget ListPopupWindow e PopupMenu possono essere implementati utilizzando i widget PopupWindow.

In genere non esiste una soluzione unica per il backporting dei componenti della UI più recenti sui dispositivi meno recenti. Tieni presente l'esperienza utente: sui dispositivi meno recenti, gli utenti potrebbero non avere familiarità con i pattern di progettazione e i componenti della UI più recenti. Pensa a come la stessa funzionalità può essere fornita utilizzando elementi familiari. In molti casi, questo è un problema minore, ad esempio se i componenti della UI più recenti sono importanti nell'ecosistema delle applicazioni (come la barra delle azioni) o se il modello di interazione è semplice e intuitivo (ad esempio, le visualizzazioni a scorrimento che utilizzano un ViewPager).

Implementare le schede utilizzando le API precedenti

Per creare un'implementazione precedente delle schede della barra delle azioni, puoi utilizzare un TabWidget e un TabHost (in alternativa, puoi utilizzare i widget Button disposti orizzontalmente). Implementa questa funzionalità nelle classi denominate TabHelperEclair e CompatTabEclair, poiché questa implementazione utilizza le API introdotte al più tardi in Android 2.0 (Eclair).

Diagramma delle classi per l'implementazione delle schede di Eclair.
Figura 1. Diagramma delle classi per l'implementazione delle schede di Eclair.

L'implementazione CompatTabEclair archivia le proprietà delle schede, come il testo e l'icona della scheda, nelle variabili di istanza, poiché non è disponibile un oggetto ActionBar.Tab per gestire questo spazio di archiviazione:

Kotlin

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.)
}

Java

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'TabHelperEclair implementazione utilizza i metodi del TabHost widget per creare TabHost.TabSpec oggetti e indicatori di schede:

Kotlin

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.
}

Java

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 sui dispositivi con Android 3.0 o versioni successive e utilizza le nuove API e un'altra che funziona sui dispositivi con Android 2.0 o versioni successive e utilizza le API precedenti. La lezione successiva spiega come utilizzare queste implementazioni nella tua applicazione.