En esta lección, se explica cómo crear una implementación que duplique las API más nuevas y sea compatible con los dispositivos más antiguos.
Cómo decidir una solución alternativa
La tarea más desafiante en relación con el uso de nuevas funciones de IU de una manera retrocompatible es decidir e implementar una solución más antigua (resguardo) para versiones más antiguas de la plataforma. En muchos casos, es posible cumplir el propósito de estos componentes de IU más recientes con funciones de marcos de trabajo de IU antiguas. Por ejemplo:
-
Se pueden implementar las barras de acciones con un
LinearLayout
horizontal que contenga botones de imagen, ya sea como barras de título personalizadas o como vistas en el diseño de la actividad. Se pueden presentar acciones de ampliación debajo del botón Menú del dispositivo. -
Se pueden implementar pestañas de barra de acciones con un
LinearLayout
horizontal que contenga botones o con el elemento de IUTabWidget
. -
Se pueden implementar los widgets
NumberPicker
ySwitch
con los widgetsSpinner
yToggleButton
, respectivamente. -
Se pueden implementar los widgets
ListPopupWindow
yPopupMenu
con los widgetsPopupWindow
.
Por lo general, no existe una sola solución para todos los componentes de IU más recientes en dispositivos más antiguos. Ten en cuenta la experiencia del usuario: en dispositivos más antiguos, es posible que los usuarios no estén familiarizados con los patrones de diseño y los componentes de IU más recientes. Piensa en cómo se puede ofrecer la misma funcionalidad con elementos conocidos. En muchos casos, esto no es una preocupación, si se destacan los componentes de la IU más recientes en el ecosistema de la aplicación (como la barra de acciones) o si el modelo de interacción es tan extremadamente simple como intuitivo (como deslizar vistas con un ViewPager
).
Cómo implementar pestañas con API antiguas
Para crear una implementación más antigua de las pestañas de la barra de acciones, puedes usar un TabWidget
y TabHost
(aunque alternativamente puedes usar widgets Button
con diseño horizontal). Implementa esto en las clases TabHelperEclair
y CompatTabEclair
, ya que esa implementación usa API ingresadas antes de Android 2.0 (Eclair).
![Diagrama de clases para la implementación de pestañas en Eclair](https://developer.android.google.cn/static/images/training/backward-compatible-ui-classes-eclair.png?authuser=7&hl=es)
Figura 1: Diagrama de clases para la implementación de pestañas en Eclair
La implementación de CompatTabEclair
almacena las propiedades de la pestaña, como el texto y el ícono de la pestaña, en las variables de instancia, ya que no hay un objeto ActionBar.Tab
disponible para manejar este almacenamiento:
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.) }
La implementación de TabHelperEclair
usa métodos en el widget TabHost
para crear objetos TabHost.TabSpec
e indicadores de pestañas:
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. }
Ahora tienes dos implementaciones de CompatTab
y TabHelper
: una que funciona en dispositivos con Android 3.0 o versiones posteriores y usa APIs nuevas, y otra que funciona en dispositivos con Android 2.0 o versiones posteriores y usa APIs anteriores. En la siguiente lección, se analiza el uso de estas implementaciones en tu aplicación.