Créer une implémentation avec d'anciennes API
Restez organisé à l'aide des collections
Enregistrez et classez les contenus selon vos préférences.
Cette leçon explique comment créer une implémentation qui reflète les API les plus récentes tout en étant compatible avec les appareils plus anciens.
Choisir une solution de substitution
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 de remplir l'objectif de ces nouveaux composants d'UI à l'aide de fonctionnalités plus anciennes du 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 respectivement à l'aide des widgets Spinner
et ToggleButton
.
-
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, cela est moins problématique si les composants d'UI les plus récents sont proéminents 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 (par exemple, les vues à balayer à 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 cela dans les classes appelées TabHelperEclair
et CompatTabEclair
, car cette implémentation utilise des API introduites au plus tard à Android 2.0 (Eclair).
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 des méthodes sur le
Widget TabHost
pour créer des TabHost.TabSpec
des objets et des indicateurs d'onglets:
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.
Le contenu et les exemples de code de cette page sont soumis aux licences décrites dans la Licence de contenu. Java et OpenJDK sont des marques ou des marques déposées d'Oracle et/ou de ses sociétés affiliées.
Dernière mise à jour le 2025/07/27 (UTC).
[[["Facile à comprendre","easyToUnderstand","thumb-up"],["J'ai pu résoudre mon problème","solvedMyProblem","thumb-up"],["Autre","otherUp","thumb-up"]],[["Il n'y a pas l'information dont j'ai besoin","missingTheInformationINeed","thumb-down"],["Trop compliqué/Trop d'étapes","tooComplicatedTooManySteps","thumb-down"],["Obsolète","outOfDate","thumb-down"],["Problème de traduction","translationIssue","thumb-down"],["Mauvais exemple/Erreur de code","samplesCodeIssue","thumb-down"],["Autre","otherDown","thumb-down"]],["Dernière mise à jour le 2025/07/27 (UTC)."],[],[],null,["# Create an implementation with older APIs\n\nThis lesson discusses how to create an implementation that mirrors newer APIs yet supports older devices.\n\nDecide on a substitute solution\n-------------------------------\n\nThe most challenging task in using newer UI features in a backward-compatible way is deciding on and implementing an older (fallback) solution for older platform versions. In many cases, it's possible to fulfill the purpose of these newer UI components using older UI framework features. For example:\n\n- Action bars can be implemented using a horizontal [LinearLayout](/reference/android/widget/LinearLayout) containing image buttons, either as custom title bars or as views in your activity layout. Overflow actions can be presented under the device *Menu* button.\n\n- Action bar tabs can be implemented using a horizontal [LinearLayout](/reference/android/widget/LinearLayout) containing buttons, or using the [TabWidget](/reference/android/widget/TabWidget) UI element.\n\n- [NumberPicker](/reference/android/widget/NumberPicker) and [Switch](/reference/android/widget/Switch) widgets can be implemented using [Spinner](/reference/android/widget/Spinner) and [ToggleButton](/reference/android/widget/ToggleButton) widgets, respectively.\n\n- [ListPopupWindow](/reference/android/widget/ListPopupWindow) and [PopupMenu](/reference/android/widget/PopupMenu) widgets can be implemented using [PopupWindow](/reference/android/widget/PopupWindow) widgets.\n\nThere generally isn't a one-size-fits-all solution for backporting newer UI components to older devices. Be mindful of the user experience: on older devices, users may not be familiar with newer design patterns and UI components. Give some thought as to how the same functionality can be delivered using familiar elements. In many cases this is less of a concern---if newer UI components are prominent in the application ecosystem (such as the action bar), or where the interaction model is extremely simple and intuitive (such as swipe views using a [ViewPager](/reference/androidx/viewpager/widget/ViewPager)).\n\nImplement tabs using older APIs\n-------------------------------\n\nTo create an older implementation of action bar tabs, you can use a [TabWidget](/reference/android/widget/TabWidget) and [TabHost](/reference/android/widget/TabHost) (although one can alternatively use horizontally laid-out [Button](/reference/android/widget/Button) widgets). Implement this in classes called `TabHelperEclair` and `CompatTabEclair`, since this implementation uses APIs introduced no later than Android 2.0 (Eclair).\n\n**Figure 1.** Class diagram for the Eclair implementation of tabs.\n\nThe `CompatTabEclair` implementation stores tab properties such as the tab text and icon in instance variables, since there isn't an [ActionBar.Tab](/reference/android/app/ActionBar.Tab) object available to handle this storage: \n\n### Kotlin\n\n```kotlin\nclass CompatTabEclair internal constructor(val activity: FragmentActivity, tag: String) :\n CompatTab(tag) {\n\n // Store these properties in the instance,\n // as there is no ActionBar.Tab object.\n private var text: CharSequence? = null\n ...\n\n override fun setText(resId: Int): CompatTab {\n // Our older implementation simply stores this\n // information in the object instance.\n text = activity.resources.getText(resId)\n return this\n }\n\n ...\n // Do the same for other properties (icon, callback, etc.)\n}\n```\n\n### Java\n\n```java\npublic class CompatTabEclair extends CompatTab {\n // Store these properties in the instance,\n // as there is no ActionBar.Tab object.\n private CharSequence text;\n ...\n\n public CompatTab setText(int resId) {\n // Our older implementation simply stores this\n // information in the object instance.\n text = activity.getResources().getText(resId);\n return this;\n }\n\n ...\n // Do the same for other properties (icon, callback, etc.)\n}\n```\n\nThe `TabHelperEclair` implementation makes use of methods on the\n[TabHost](/reference/android/widget/TabHost) widget for creating [TabHost.TabSpec](/reference/android/widget/TabHost.TabSpec)\nobjects and tab indicators: \n\n### Kotlin\n\n```kotlin\nclass TabHelperEclair internal constructor(activity: FragmentActivity) : TabHelper(activity) {\n\n private var tabHost: TabHost? = null\n ...\n\n override fun setUp() {\n // Our activity layout for pre-Honeycomb devices\n // must contain a TabHost.\n tabHost = tabHost ?: mActivity.findViewById\u003cTabHost\u003e(android.R.id.tabhost).apply {\n setup()\n }\n }\n\n override fun addTab(tab: CompatTab) {\n ...\n tabHost?.newTabSpec(tab.tag)?.run {\n setIndicator(tab.getText()) // And optional icon\n ...\n tabHost?.addTab(this)\n }\n }\n // The other important method, newTab() is part of\n // the base implementation.\n}\n```\n\n### Java\n\n```java\npublic class TabHelperEclair extends TabHelper {\n private TabHost tabHost;\n ...\n\n protected void setUp() {\n if (tabHost == null) {\n // Our activity layout for pre-Honeycomb devices\n // must contain a TabHost.\n tabHost = (TabHost) mActivity.findViewById(\n android.R.id.tabhost);\n tabHost.setup();\n }\n }\n\n public void addTab(CompatTab tab) {\n ...\n TabSpec spec = tabHost\n .newTabSpec(tag)\n .setIndicator(tab.getText()); // And optional icon\n ...\n tabHost.addTab(spec);\n }\n\n // The other important method, newTab() is part of\n // the base implementation.\n}\n```\n\nYou now have two implementations of `CompatTab` and `TabHelper`: one that works on devices running Android 3.0 or later and uses new APIs, and another that works on devices running Android 2.0 or later and uses older APIs. The next lesson discusses using these implementations in your application."]]