Utilizza il componente sensibile alla versione

Ora che hai due implementazioni di TabHelper e CompatTab, una per Android 3.0 e versioni successive e una per le versioni precedenti della piattaforma, è il momento di fare qualcosa con queste implementazioni. Questa lezione illustra la creazione della logica per passare da un'implementazione all'altra, la creazione di layout compatibili con le versioni e, infine, l'utilizzo del componente UI compatibile con le versioni precedenti.

Aggiungere la logica di commutazione

La classe astratta TabHelper funge da factory per la creazione di istanze TabHelper e CompatTab appropriate per la versione, in base alla versione della piattaforma del dispositivo corrente:

Kotlin

sealed class TabHelper(protected val mActivity: FragmentActivity, protected val tag: String) {

    abstract fun setUp()

    abstract fun addTab(tab: CompatTab)

    // Usage is tabHelper.newTab("tag")
    fun newTab(tag: String): CompatTab =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                CompatTabHoneycomb(mActivity, tag)
            } else {
                CompatTabEclair(mActivity, tag)
            }

    companion object {
        // Usage is TabHelper.createInstance(activity)
        fun createInstance(activity: FragmentActivity): TabHelper =
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                    TabHelperHoneycomb(activity)
                } else {
                    TabHelperEclair(activity)
                }
    }
}

Java

public abstract class TabHelper {
    ...
    // Usage is TabHelper.createInstance(activity)
    public static TabHelper createInstance(FragmentActivity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            return new TabHelperHoneycomb(activity);
        } else {
            return new TabHelperEclair(activity);
        }
    }

    // Usage is tabHelper.newTab("tag")
    public CompatTab newTab(String tag) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            return new CompatTabHoneycomb(mActivity, tag);
        } else {
            return new CompatTabEclair(mActivity, tag);
        }
    }
    ...
}

Creare un layout dell'attività compatibile con le versioni

Il passaggio successivo consiste nel fornire layout per l'attività in grado di supportare le due implementazioni delle schede. Per l'implementazione precedente (TabHelperEclair), devi assicurarti che il layout dell'attività contenga un TabWidget e un TabHost, nonché un contenitore per i contenuti delle schede:

res/layout/main.xml:

<!-- This layout is for API level 5-10 only. -->
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dp">

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

    </LinearLayout>
</TabHost>

Per l'implementazione TabHelperHoneycomb, è sufficiente un FrameLayout per contenere i contenuti delle schede, poiché gli indicatori delle schede sono forniti dall'ActionBar:

res/layout-v11/main.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabcontent"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

In fase di runtime, Android deciderà quale versione del layout main.xml espandere a seconda della versione della piattaforma. Si tratta della stessa logica mostrata nella sezione precedente per determinare quale implementazione di TabHelper utilizzare.

Utilizzare TabHelper nell'attività

Nel metodo onCreate() dell'attività, puoi ottenere un oggetto TabHelper e aggiungere schede con il seguente codice:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    setContentView(R.layout.main)

    TabHelper.createInstance(this).apply {
        setUp()

        newTab("photos")
                .setText(R.string.tab_photos)
                .also { photosTab ->
                    addTab(photosTab)
                }

        newTab("videos")
                .setText(R.string.tab_videos)
                .also { videosTab ->
                    addTab(videosTab)
                }
    }
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.main);

    TabHelper tabHelper = TabHelper.createInstance(this);
    tabHelper.setUp();

    CompatTab photosTab = tabHelper
            .newTab("photos")
            .setText(R.string.tab_photos);
    tabHelper.addTab(photosTab);

    CompatTab videosTab = tabHelper
            .newTab("videos")
            .setText(R.string.tab_videos);
    tabHelper.addTab(videosTab);
}

Quando esegui l'applicazione, questo codice espande il layout dell'attività corretto e crea un'istanza di un oggetto TabHelperHoneycomb o TabHelperEclair. La classe concreta effettivamente utilizzata è opaca per l'attività, poiché condividono l'interfaccia comune TabHelper.

Di seguito sono riportati due screenshot che mostrano questa implementazione in esecuzione su un dispositivo Android 2.3 e Android 4.0.

Esempio di schede in esecuzione su un dispositivo Android 2.3 (utilizzando TabHelperEclair).
Esempio di schede in esecuzione su un dispositivo Android 4.0 (utilizzando TabHelperHoneycomb).

Figura 1. Esempi di screenshot di schede compatibili con le versioni precedenti in esecuzione su un dispositivo Android 2.3 (che utilizza TabHelperEclair) e un dispositivo Android 4.0 (che utilizza TabHelperHoneycomb).