Créer une implémentation avec d'anciennes API

Cette leçon explique comment créer une implémentation qui reflète les API plus récentes, tout en prenant en charge les appareils plus anciens.

Décider d'une solution de remplacement

La tâche la plus difficile pour utiliser les nouvelles fonctionnalités de l'interface utilisateur de manière rétrocompatible est de choisir et d'implémenter une solution plus ancienne (de remplacement) pour les anciennes versions de la plate-forme. Dans de nombreux cas, il est possible d'atteindre l'objectif de ces nouveaux composants d'UI à l'aide d'anciennes fonctionnalités de framework d'UI. Exemple :

  • Les barres d'action peuvent être implémentées à l'aide d'un LinearLayout horizontal contenant des boutons d'image, soit en tant que barres de titre personnalisées, soit en tant que vues dans la mise en page de votre activité. Les actions de dépassement de capacité peuvent être affichées sous le bouton Menu de l'appareil.

  • Vous pouvez implémenter les onglets de la barre d'action à l'aide d'un LinearLayout horizontal contenant des boutons, ou à l'aide de l'élément d'interface utilisateur TabWidget.

  • Les widgets NumberPicker et Switch peuvent être implémentés à l'aide des widgets Spinner et ToggleButton, respectivement.

  • Les widgets ListPopupWindow et PopupMenu peuvent être implémentés à l'aide de widgets PopupWindow.

Il n'existe généralement pas de solution unique pour rétroporter les composants d'interface utilisateur les plus récents sur des appareils plus anciens. Soyez attentif à l'expérience utilisateur: sur les appareils plus anciens, les utilisateurs peuvent ne pas être familiers avec les nouveaux modèles de conception et les nouveaux composants d'interface utilisateur. Réfléchissez à la manière dont la même fonctionnalité peut être fournie à l'aide d'éléments familiers. Dans de nombreux cas, ce n'est pas un problème, si les nouveaux composants d'UI sont importants dans l'écosystème de l'application (comme la barre d'action) ou si le modèle d'interaction est extrêmement simple et intuitif (comme les vues de balayage à l'aide d'un ViewPager).

Implémenter des onglets à l'aide d'anciennes API

Pour créer une implémentation plus ancienne des onglets de la barre d'action, vous pouvez utiliser TabWidget et TabHost (bien que vous puissiez également utiliser des widgets Button disposés horizontalement). Implémentez-le dans les classes appelées TabHelperEclair et CompatTabEclair, car cette implémentation utilise des API introduites au plus tard dans Android 2.0 (Eclair).

Schéma de classe pour l'implémentation Eclair des onglets.

Figure 1 : Schéma de classe pour l'implémentation Eclair des onglets.

L'implémentation CompatTabEclair stocke les propriétés des onglets, telles que le texte et l'icône de l'onglet, dans les variables d'instance, car aucun objet ActionBar.Tab n'est disponible pour gérer ce stockage:

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'implémentation de TabHelperEclair utilise les méthodes du widget TabHost pour créer des objets TabHost.TabSpec et des indicateurs d'onglet:

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

Vous disposez désormais de deux implémentations de CompatTab et TabHelper: l'une fonctionne sur les appareils équipés d'Android 3.0 ou version ultérieure et utilise de nouvelles API, et l'autre fonctionne sur les appareils équipés d'Android 2.0 ou version ultérieure et utilise d'anciennes API. La leçon suivante traite de l'utilisation de ces implémentations dans votre application.