El SDK de Android 5.0 incorpora nuevos widgets para la UI y material design, nuestro lenguaje visual enfocado para tener un buen diseño. Para ser capaz de proporcionar los últimos diseños a las versiones más antiguas de Android, hemos mejorado nuestras librerías de soporte, incluyendo una gran actualización de AppCompat v21, así como las nuevas librerías RecyclerView, CardView y Palette.
En esta entrada echaremos un vistazo a las nuevas características existentes en AppCompat v21 y como puedes usarlas para que tus apps soporten material design.
Contenidos
¿Que hay nuevo en AppCompat v21?
AppCompat (también conocido como ActionBarCompat) se implementó en la API de la ActionBar de Android 4.0 para dispositivos que ejecutaban Gingerbread, proporcionando una API común para su implementación. AppCompat v21 se actualiza con Android 5.0.
En esta versión, Android introduce un nuevo Widget llamado Toolbar . Es una generalización de la Action Bar y te permite mucho más control y flexibilidad sobre la misma. Toolbar es una vista dentro de tu jerarquía, como cualquier otra, facilitando la combinación con el resto de tus vistas, animarla, y reaccionar a los eventos de scroll. Puedes también configurar este widget como la action bar de tu Actividad, es decir, las acciones del menú de opciones estándar se mostrarán dentro del widget Toolbar.
Si has estado usando la última actualización de AppCompat v21, verás que ya ha sido implementada en varias apps de Google como puede ser Play Store o Kiosko. También se ha integrado en la app Google I/O, como se puede ver en la imagen superior. Esta app es open source.
Configurar
Si estás usando Gradle, añade appcompat v21 como una dependencia en tu archivo build.gradle:
0 1 2 3 4 |
dependencies { compile "com.android.support:appcompat-v7:21.0.+" } |
Nueva integración
- Todas tus actividades deben extender ActionBarActivity, el cual extiende FragmentActivity de la librería de soporte v4, así que puedes continuar usando fragments.
- Todos tus temas (que quieran una Action Bar/Toolbar) deben heredar desde Theme.AppCompat. Hay variantes disponibles, incluyendo Light y NoActionBar.
- Cuando infles cualquier elemento para que se muestre sobre la Action Bar (como los SpinnerAdapter para una lista de navegación en la toolbar), asegúrate que usas el contexto tematizado de la action bar, recuperado vía getSupportActionBar().getThemedContext().
- Debes usar métodos estáticos en MenuItemCompat para cualquier acción relacionada con llamadas a un MenuItem.
Para más información, visita la guía de la API de la Action Bar la cual es una guía comprensiva sobre AppCompat.
Migrar desde configuraciones previas
0 1 2 3 4 5 6 7 8 9 10 11 |
<style name="Theme.MyTheme" parent="Theme.AppCompat.Light"> <!-- Set AppCompat’s actionBarStyle --> <item name="actionBarStyle">@style/MyActionBarStyle</item> <!-- Set AppCompat’s color theming attrs --> <item name=”colorPrimary”>@color/my_awesome_red</item> <item name=”colorPrimaryDark”>@color/my_awesome_darker_red</item> <!-- The rest of your attributes --> </style> |
Ahora puedes eliminar todos los estilos values-v14+ de Action Bar.
Tematizar
AppCompat v21 tiene soporte para los nuevos atributos, tema y paleta de colores, los cuales te permiten fácilmente personalizar tu tema para ajustarte a tu marca con los colores primary y accent. Por ejemplo:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<style name="Theme.MyTheme" parent="Theme.AppCompat.Light"> <!-- colorPrimary is used for the default action bar background --> <item name=”colorPrimary”>@color/my_awesome_color</item> <!-- colorPrimaryDark is used for the status bar --> <item name=”colorPrimaryDark”>@color/my_awesome_darker_color</item> <!-- colorAccent is used as the default value for colorControlActivated, which is used to tint widgets --> <item name=”colorAccent”>@color/accent</item> <!-- You can also set colorControlNormal, colorControlActivated colorControlHighlight, and colorSwitchThumbNormal. --> </style> |
Cuando tu configures esos atributos, AppCompat v21 automáticamente propagara sus valores a los atributos del framework con API 21+. También cambiará automáticamente los colores de la barra de estado (status bar) y de la tarea en la vista recientes (Overview task entry).
Para plataformas más antiguas, AppCompat v21 emula el color del tema seleccionado donde es posible. En este momento está limitado a la barra de acciones y algunos widgets.
- colorControlNormal: Este color se aplica a los widgets cuando están en estado normal, por ejemplo cuando un Check Box no está activado.
- colorControlActivated: Este color se aplica a los widgets cuando están en estado activado, por ejemplo cuando un Switch está activado.
- colorControlHightlight: Este color se aplica al efecto de los widgets (Ripples, list selectors, etc), por ejemplo cuando pulsas un botón, el color del ripple en vez de ser gris sería del color seleccionado.
- colorButtonNormal: Este color se aplica a los botones en estado normal (actualmente no se que hace, ya que en teoría debería cambiar el color del botón, pero no funciona ya que parece que los botones todavía no están implementados en la AppCompat v21).
- colorControlThumbNormal: Este color se aplica a los Switch thumbs en su estado normal.
Tintado de Widgets
Cuando usas dispositivos con Android 5.0, todos los widgets son tintados usando los atributos de colores del tema. Hay dos principales características que permiten esto en Lollipop: tintado de drawables y referenciar los atributos del tema (de la forma ?attr/foo) en los drawables.
AppCompat v21 proporciona comportamientos similares en versiones previas de Android para un subconjunto de widgets de la interfaz de usuario:
- Todo lo que proporcione la Toolbar de AppCompat v21 (modos de acción, etc)
- EditText
- Spinner
- CheckBox
- RadioButton
- Switch (usa el nuevo android.support.v7.widget.SwitchCompat)
- CheckedTextView
No necesitas hacer nada especial para conseguir que funcione, solo usar esos controles en tus layouts como lo haces normalmente y AppCompat v21 hará el resto (con algunas advertencias; mira el FAQ de abajo).
Widget Toolbar
La Toolbar (barra de herramientas) está completamente soportada en AppCompat v21 y tiene características y una API con el widget del framework. En AppCompat, la Toolbar esta implementada en la clase android.support.v7.widget.Toolbar. Hay dos formas de usar Toolbar:
- Usa la Toolbar como una Action Bar cuando quieras usar las facilidades existentes en la Action Bar (como un menú overflow o de selección, ActionBarDrawerToggle, y otros) pero quieres tener más control sobre su apariencia.
- Usa la Toolbar de forma independiente cuando quieras usar las pautas en tu app para situaciones en las que una Action Bar no sería soportada; por ejemplo, mostrar múltiples toolbars en la pantalla, abarcar solo una parte de la anchura, y otros.
Action Bar (Barra de Acciones)
Para usar la Toolbar como una Action Bar, primero deshabilita la Action Bar proporcionada. La forma más fácil para hacer esto es extender tu tema con Theme.AppCompat.NoActionBar (o su variante clara en vez de la oscura).
Segundo, crea una instancia de la Toolbar, usualmente usando el XML de tu layout:
0 1 2 3 4 5 |
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content"/> |
Puedes incluir directamente el código de arriba en tu layout en lugar de crear el archivo toolbar.xml, o incluir en toolbar.xml en tus layouts con:
0 1 2 |
<include layout="@layout/toolbar"/> |
La altura, anchura, fondo y otros elementos son pueden ser modificados libremente. Como la Toolbar es solo un ViewGroup, puedes cambiar su estilo y posición como tu quieras.
Entonces en tu Activity o Fragment, selecciona la Toolbar como tu Action Bar:
0 1 2 3 4 5 6 7 8 9 |
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.blah); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); } |
Desde este punto, todos los elementos del menú se muestran en tu Toolbar, a través de las llamadas al menú de opciones estándar.
Independiente
La diferencia en el modo independiente es que no seleccionas la Toolbar para actuar como tu action bar. Por esta razón, puedes usar cualquier tema del AppCompat v21 sin tener que deshabilitar la Action Bar proporcionada.
En el modo independiente, necesitas añadir manualmente los contenidos y acciones de la Toolbar. Por ejemplo, si quieres mostrar acciones, necesitas inflar un menú dentro de ella:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.blah); Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar); // Set an OnMenuItemClickListener to handle menu item clicks toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { // Handle the menu item return true; } }); // Inflate a menu to be displayed in the toolbar toolbar.inflateMenu(R.menu.your_toolbar_menu); } |
Hay otras muchas cosas que tu puedes hacer con la Toolbar. Para más información, visita Toolbar API reference.
Estilizar
Estilizar la Toolbar se consigue de forma diferente a la action bar estándar, y es seleccionada directamente dentro de la vista.
Aquí hay un estilo básico que deberías usar cuando estés usando una Toolbar como tu action bar:
0 1 2 3 4 5 6 |
<android.support.v7.widget.Toolbar android:layout_height="wrap_content" android:layout_width="match_parent" android:minHeight="?attr/actionBarSize" app:theme="@style/ThemeOverlay.AppCompat.ActionBar"/> |
La declaración app:theme se asegurará de que tus textos y elementos usen colores sólidos (es decir, 100% de opacidad blanca).
DarkActionBar (Barra de Acciones Oscura)
Puedes estilizar la Toolbar directamente usando los atributos del layout. Para conseguir que la Toolbar se vea como una ‘DarkActionBar’ (contenido oscuro con el menú overflow blanco), proporciona los atributos del tema y el popupTheme:
0 1 2 3 4 5 6 |
<android.support.v7.widget.Toolbar android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="@dimen/triple_height_toolbar" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/> |
SearchViewWidget
AppCompat v21 ofrece la API actualizada de Lollipop SearchView, la cual permite muchas mas configuraciones y estilos. Ahora usaremos la estructura de estilos de Lollipop en lugar de los atributos de tema de la antigua SearchView.
Así puedes estilizar la SearchView:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<style name="Theme.MyTheme" parent="Theme.AppCompat"> <item name="searchViewStyle">@style/MySearchViewStyle</item> </style> <style name="MySearchViewStyle" parent="Widget.AppCompat.SearchView"> <!-- Background for the search query section (e.g. EditText) --> <item name="queryBackground">...</item> <!-- Background for the actions section (e.g. voice, submit) --> <item name="submitBackground">...</item> <!-- Close button icon --> <item name="closeIcon">...</item> <!-- Search button icon --> <item name="searchIcon">...</item> <!-- Go/commit button icon --> <item name="goIcon">...</item> <!-- Voice search button icon --> <item name="voiceIcon">...</item> <!-- Commit icon shown in the query suggestion row --> <item name="commitIcon">...</item> <!-- Layout for query suggestion rows --> <item name="suggestionRowLayout">...</item> </style> |
No necesitas seleccionar todos (o ninguno) de esos elementos, los elementos por defecto funcionarán con la gran mayoría de las apps.
La Toolbar está llegando…
Afortunadamente este post te ayudará a conseguir ejecutar tu app con AppCompat v21 y permitirte creer apps con el increíble diseño material design.
FAQ
¿Por qué mi EditText (u otro widget mencionado anteriormente) no se tinta correctamente en mi dispositivo con una versión anterior a Lollipop?
El tintado de widgets en AppCompat v21 funciona mediante la intercepción de cualquier inflación de un layout e insertando una versión de un tinte especial del widget en su lugar. Para la mayoría de las personas esto funcionará bien, pero puedo pensar un par de escenarios donde esto no funcionará, incluyendo:
- Tienes tu propia versión personalizada del widget (es decir, tu has extendido EditText)
- Estás creando el EditText sin un LayoutInflater (es decir, llamando a new EditText()).
Los widgets con el tinte especial están actualmente ocultos hasta que ellos estén completamente implementados. Esto puede cambiar en el futuro.
¿Por qué X widget no está estilizado con material design cuando ejecuto en versiones anteriores a pre-Lollipop?
Solo algunos widget de los más usuales han sido actualizados. Hay muchos más que serán actualizados en futuras versiones de AppCompat.
¿Por qué mi Action Bar tiene una sombra en dispositivos con Android Lollipop? Yo he seleccionado android:windowContentOverlay como null.
En Lollipop, la sombra de la action bar se proporciona usando la nueva API de elevación. Para eliminarla, llama a getSupportActionBar().setElevation(0), o añade el valor 0 al atributo de elevación en tu estilo de la Action Bar.
¿Por qué no hay ripples en versiones pre-Lollipop?
Lo que permite que RippleDrawable funcione suavemente en Android 5.0 es el nuevo RenderThread. Para optimizar el rendimiento en versiones anteriores de Android, hemos dejado de lado RippleDrawable por ahora.
¿Como uso AppCompat v21 con Preferencias?
Puedes continuar usando el PreferenceFragment en tu ActionBarActivity cuando ejecutes tu app en dispositivos con una API v11+. Para dispositivos anteriores a esos, necesitarás proporcional una PreferenceActivity normal el cual no está estilizado con material design.
Fuente original, autor Chris Banes