Estrarre le nuove API

Supponi di voler utilizzare le schede della barra delle azioni come forma principale di navigazione di primo livello nella tua applicazione. Purtroppo le API ActionBar sono disponibili solo in Android 3.0 o versioni successive (livello API 11 e versioni successive). Pertanto, se vuoi distribuire la tua applicazione su dispositivi che eseguono versioni precedenti della piattaforma, devi fornire un'implementazione che supporti l'API più recente, fornendo al contempo un meccanismo di fallback che utilizzi API meno recenti.

In questo corso, creerai un componente di interfaccia utente a schede che utilizza classi astratte con implementazioni specifiche per la versione per garantire la compatibilità con le versioni precedenti. Questa lezione descrive come creare un livello di astrazione per le nuove API di tabulazione come primo passo verso la creazione del componente Tab.

Preparati all'astrazione

L'astrazione nel linguaggio di programmazione Java prevede la creazione di una o più interfacce o classi astratte per nascondere i dettagli dell'implementazione. Nel caso delle API Android più recenti, puoi usare l'astrazione per creare componenti sensibili alle versioni che usano le API attuali sui dispositivi più recenti e ricorrere ad API meno recenti e più compatibili sui dispositivi meno recenti.

Quando utilizzi questo approccio, innanzitutto determini quali classi più recenti vuoi essere in grado di utilizzare in modo compatibile con le versioni precedenti, quindi crei classi astratte in base alle interfacce pubbliche delle classi più recenti. Nella definizione delle interfacce di astrazione, devi eseguire il mirroring quanto più possibile della nuova API. Questo massimizza la compatibilità con il futuro e semplifica il rilascio dello strato di astrazione in futuro quando non sarà più necessario.

Dopo aver creato classi astratte per queste nuove API, è possibile creare e scegliere un numero qualsiasi di implementazioni durante il runtime. Ai fini della compatibilità con le versioni precedenti, queste implementazioni possono variare in base al livello API richiesto. Pertanto, un'implementazione può utilizzare API rilasciate di recente, mentre altre possono utilizzare API meno recenti.

Creare un'interfaccia a schede astratta

Per creare una versione delle schede compatibile con le versioni precedenti, devi prima determinare quali funzionalità e API specifiche sono necessarie per la tua applicazione. Nel caso delle schede della sezione di primo livello, supponiamo che tu disponga dei seguenti requisiti funzionali:

  1. Gli indicatori delle schede dovrebbero mostrare del testo e un'icona.
  2. Le schede possono essere associate a un'istanza di frammento.
  3. L'attività dovrebbe essere in grado di rilevare le modifiche alla scheda.

La preparazione anticipata di questi requisiti ti consente di controllare l'ambito del livello di astrazione. Ciò significa che puoi dedicare meno tempo alla creazione di più implementazioni del livello di astrazione e iniziare a utilizzare prima la nuova implementazione compatibile con le versioni precedenti.

Le API principali per le schede sono in ActionBar e ActionBar.Tab. Si tratta delle API di cui eseguire l'astrazione per rendere le tue schede sensibili alla versione. I requisiti di questo progetto di esempio richiamano la compatibilità con Eclair (livello API 5) e sfrutta al contempo le nuove funzionalità della scheda in Honeycomb (livello API 11). Di seguito è riportato un diagramma della struttura delle classi a supporto di queste due implementazioni e le rispettive classi base astratte (o interfacce).

Diagramma delle classi di base astratte e delle implementazioni specifiche per la versione.

Figura 1. Diagramma delle classi di base astratte e delle implementazioni specifiche per la versione.

ActionBar.Tab astratta

Inizia a creare il tuo livello di astrazione delle schede creando una classe astratta che rappresenti una scheda, che rispecchi l'interfaccia ActionBar.Tab:

Kotlin

sealed class CompatTab(val tag: String) {
    ...
    abstract fun getText(): CharSequence
    abstract fun getIcon(): Drawable
    abstract fun getCallback(): CompatTabListener
    abstract fun getFragment(): Fragment

    abstract fun setText(text: String): CompatTab
    abstract fun setIcon(icon: Drawable): CompatTab
    abstract fun setCallback(callback: CompatTabListener): CompatTab
    abstract fun setFragment(fragment: Fragment): CompatTab
    ...
}

Java

public abstract class CompatTab {
    ...
    public abstract CompatTab setText(int resId);
    public abstract CompatTab setIcon(int resId);
    public abstract CompatTab setTabListener(
            CompatTabListener callback);
    public abstract CompatTab setFragment(Fragment fragment);

    public abstract CharSequence getText();
    public abstract Drawable getIcon();
    public abstract CompatTabListener getCallback();
    public abstract Fragment getFragment();
    ...
}

In questo caso, puoi utilizzare una classe astratta anziché un'interfaccia per semplificare l'implementazione di funzionalità comuni come l'associazione degli oggetti Tab alle attività (non mostrate nello snippet di codice).

Metodi della scheda della ActionBar astratta

In seguito, definisci una classe astratta che ti consenta di creare e aggiungere schede a un'attività, come ActionBar.newTab() e ActionBar.addTab():

Kotlin

sealed class TabHelper(protected val activity: FragmentActivity) {
    ...

    abstract fun setUp()

    fun newTab(tag: String): CompatTab {
        // This method is implemented in a later lesson.
    }

    abstract fun addTab(tab: CompatTab)

    ...
}

Java

public abstract class TabHelper {
    ...

    public CompatTab newTab(String tag) {
        // This method is implemented in a later lesson.
    }

    public abstract void addTab(CompatTab tab);

    ...
}

Nelle prossime lezioni creerai implementazioni per TabHelper e CompatTab che funzionano su entrambe le versioni della piattaforma, vecchie e nuove.

Dovresti leggere anche