La app bar, o también llamada action bar, es la barra de título y herramientas que aparece en la parte superior de la gran mayoría de aplicaciones actuales de la plataforma Android.
La app bar normalmente muestra el título de la aplicación o la actividad en la que nos encontramos, una serie de botones de acción, y un menú desplegable (menú de overflow) donde se incluyen más acciones que no tienen espacio para mostrarse como botón o simplemente no se quieren mostrar como tal.
A la izquierda del título de la aplicación también puede aparecer en ocasiones el icono de navegación, que suele avisar de la existencia de menú lateral deslizante (navigation drawer), o el botón de navegación hacia atrás/arriba (up action), pero esto ya lo veremos más adelante.
En la actualidad, Android proporciona este componente a través de la librería appcompat, que suele venir ya incluida por defecto en todos nuestros proyectos, la podemos encontrar en la sección dependencies
del fichero build.gradle:
dependencies { ... implementation 'androidx.appcompat:appcompat:1.1.0' ... }
Podemos hacer uso de la action bar de dos formas diferentes. La primera de ellas, más sencilla aunque menos flexible, consiste en utilizar la action bar por defecto que se añade a nuestras actividades por tan sólo utilizar un tema (theme) determinado en la aplicación y extender nuestras actividades de una clase específica. La segunda, más flexible y personalizable aunque requiere más código, consiste en añadir de forma explícita un componente Toolbar
a nuestra interfaz de usuario. En este primer artículo nos centraremos en la primera de las alternativas indicadas, y en el siguiente hablaremos de Toolbar
.
Vamos a comprobar por tanto en primer lugar, aunque también debe venir configurado por defecto con un nuevo proyecto de Android Studio, que el tema utilizado por nuestra aplicación sea uno de los proporcionados por la librería appcompat. Para ello abrimos el fichero styles.xml situado en la carpeta /res/values y nos aseguramos que el tema de nuestra aplicación extiende de alguno de los temas Theme.AppCompat
disponibles, en mi caso Theme.AppCompat.Light.DarkActionBar
(fondo claro con action bar oscura):
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> .... </style> </resources>
Revisaremos en segundo lugar que nuestras actividades extienden de la clase AppCompatActivity
, de forma que puedan hacer uso de toda la funcionalidad de la action bar. En mi caso, la actividad principal está definida así:
import androidx.appcompat.app.AppCompatActivity import android.os.Bundle class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } }
Tan sólo con esto, si ejecutamos el proyecto podremos comprobar como nuestra actividad muestra la action bar en la parte superior, con el siguiente aspecto:
Como vemos, la action bar por defecto tan sólo contiene el título. El título mostrado por defecto corresponde al título de la aplicación, definido en el fichero AndroidManifest.xml, en el atributo label
del elemento application
correspondiente a dicha actividad:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.sgoliver.android.appbar"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> ... </application> </manifest>
Por su parte, los botones de acción y las opciones del menú de overflow se definen de la misma forma que los antiguos menús de aplicación que se utilizaban en versiones anteriores a Android 3.
¿Y cómo se define un menú de aplicación? Un menú se define, como la mayoría de los recursos de Android, mediante un fichero XML, y se colocará en la carpeta /res/menu. El menú se definirá mediante un elemento raiz <menu>
que contendrá una serie de elementos <item>
que representarán cada una de las opciones. Los elementos <item>
por su parte podrán incluir varios atributos que lo definan, entre los que destacan los siguientes:
android:id
. El ID identificativo del elemento, con el que podremos hacer referencia dicha opción.android:title
. El texto que se visualizará para la opción.android:icon
. El icono asociado a la acción.android:showAsAction
. Si se está mostrando una action bar, este atributo indica si la opción de menú se mostrará como botón de acción o como parte del menú de overflow. Puede tomar varios valores:ifRoom
. Se mostrará como botón de acción sólo si hay espacio disponible.withText
. Se mostrará el texto de la opción junto al icono en el caso de que éste se esté mostrando como botón de acción.never
. La opción siempre se mostrará como parte del menú de overflow.always
. La opción siempre se mostrará como botón de acción. Este valor puede provocar que los elementos se solapen si no hay espacio suficiente para ellos.
Como ejemplo, vamos a crear un menú con tres opciones: “Buscar”, “Nuevo” y «Opciones», la primera para que se muestre en la app bar, si hay espacio, como botón con su icono correspondiente, la segunda igual pero añadiendo su texto junto al icono, y la tercera para que siempre se muestre en el menú de overflow. Para ello, crearemos el fichero /res/menu/menu_main.xml con el siguiente contenido:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_buscar" android:title="@string/action_buscar" android:icon="@drawable/ic_buscar" android:orderInCategory="100" app:showAsAction="ifRoom" /> <item android:id="@+id/action_nuevo" android:title="@string/action_nuevo" android:icon="@drawable/ic_nuevo" android:orderInCategory="100" app:showAsAction="ifRoom|withText" /> <item android:id="@+id/action_opciones" android:title="@string/action_opciones" android:orderInCategory="100" app:showAsAction="never" /> </menu>
Los iconos ic_buscar e ic_nuevo los he añadido al proyecto de igual forma que en artículos anteriores, por ejemplo como vimos en el artículo sobre botones.
Como podéis ver además en la segunda opción (action_nuevo
), se pueden combinar varios valores de showAsAction
utilizando el caracter “|“.
Una vez definido el menú en su fichero XML correspondiente tan sólo queda asociarlo a nuestra actividad principal. Esto se realiza sobrescribiendo el método onCreateOptionsMenu()
de la actividad, dentro del cual lo único que tenemos que hacer normalmente es inflar el menú llamando al método inflate()
pasándole como parámetro el ID del fichero XML donde se ha definido.
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main, menu) return true } }
Ejecutemos de nuevo la aplicación a ver qué ocurre:
Como podemos observar, la opción “Opciones” se incluye dentro del menú de overflow, y aparecen como botones de acción las dos opciones que hemos marcado como showAsAction=”ifRoom”
, pero para la segunda no aparece el texto. ¿Y por qué? Porque no hay espacio disponible suficiente con la pantalla en vertical. Pero si rotamos el emulador para ver qué ocurre con la pantalla en horizontal vemos lo siguiente:
Con la pantalla en horizontal sí se muestra el texto de la segunda opción, tal como habíamos solicitado con el valor withText
del atributo showAsAction
.
Podemos seguir personalizando nuestra action bar definiendo los colores principales del tema seleccionado. Esto podemos hacerlo dentro del fichero /res/values/styles.xml, y podemos configurar tres colores principales:
colorPrimary
. Es el color principal de la aplicación, y se utilizará entre otras cosas como color de fondo de la action bar.colorPrimaryDark
. Es una variante más oscura del color principal, que por ejemplo se utilizará como color de la barra de estado (la barra superior que contiene los iconos de notificación, batería, reloj, …).colorAccent
. Suele ser el color utilizado para destacar el botón de acción principal de la aplicación (por ejemplo un botón flotante, y para otros pequeños detalles de la interfaz, como por ejemplo algunos controles, cuadros de texto o checkboxes.
En el siguiente link podéis consultar la paleta de colores estandar definida en las especificaciones de Material Design. En mi caso utilizaré el Indigo intensidad 500 como color principal (#3F51B5
), la intensidad 700 de esa misma tonalidad como variante más oscura (#303F9F
), y como color destacado el Pink (#FF4081
). Los definimos dentro del tema de la aplicación de la siguiente forma:
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> </resources>
La definición de los colores como tal se realiza en un fichero llamado colors.xml dentro de la carpeta /res/values (si no existe el fichero podemos crearlo utilizando el menú contextual sobre la carpeta /res/values, mediante la opción New / Values resource file):
<resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorAccent">#FF4081</color> </resources>
Si ejecutamos de nuevo la aplicación podemos ver los efectos (he añadido a la interfaz algunos controles para ver el efecto sobre ellos del color accent):
Por último, ahora que ya sabemos definir y personalizar los elementos de nuestra action bar queda saber cómo responder a las pulsaciones que haga el usuario sobre ellos. Para esto sobrescribiremos el método onOptionsItemSelected()
de la actividad, donde consultaremos la opción de menú que se ha pulsado mediante el método getItemId()
de la opción de menú recibida como parámetro y actuaremos en consecuencia. En mi caso de ejemplo tan sólo escribiré un mensaje al log.
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { R.id.action_opciones -> { Log.i("ActionBar", "Opciones!") true } R.id.action_nuevo -> { Log.i("ActionBar", "Nuevo!") true } R.id.action_buscar -> { Log.i("ActionBar", "Buscar!") true } else -> { super.onOptionsItemSelected(item) } }
Si ejecutamos ahora la aplicación y miramos el log mientras pulsamos las distintas opciones de la action bar veremos como se muestran los mensajes definidos.
En el siguiente artículo veremos cómo incluir la action bar de forma explícita en nuestras aplicaciones (en vez de utilizar la construida por defecto) utilizando el nuevo componente Toolbar
incluido en las últimas versiones de la librería de soporte.
Puedes consultar y/o descargar el código completo de los ejemplos desarrollados en este artículo accediendo a la pagina del curso en GitHub.
22 comentarios
Hola, buena explicación, solo tengo una duda.sé que es utilizable a partir de Android 5.0, pero ¿es posible usar esto en versiones inferiores? leí que es posible utilizar estas Action Bar desde Android 4.0, pero sin cambiar el color de la barra de notificaciones. Buen trabajo, esperando más tutoriales.
Hola Erick, no hay problema con versiones de android 4. saludos
Muchas gracias, con la respuesta, si ya lo eh comprobado. Lo que si deseo saber, es como añadir un NavigationDrawer y un GoogleMap. De nuevo muchas gracias por las respuesta.
[…] el artículo anterior vimos cómo incluir una action bar (o app bar) en nuestras aplicaciones haciendo uso de la […]
Buenas, veo que en este nuevo ActionBar la actividad extiende de «AppCompatActivity». Pero hay un problema al hacer el NavigationDrawer y usar el «ActionBarDrawerToggle». Por las normas de Material Design parece que ya no hay que poner ningún icono, es decir:
Lo que antes era así:
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.drawable.ic_navigation_drawer, R.string.drawer_open, R.string.drawer_close);
Ahora es así:
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close);
¿Qué pasa? Que al menos a mi no me funciona y en todos los ejemplos que veo la clase siguen extendiéndola de «ActionBarActivity».
Por tanto me pregunto, ¿está esto bien? Si es así, ¿cómo sería posible utilizar «AppCompatActivity» y la nueva forma del «ActionBarDrawerToggle»?
Un poco de paciencia :) Sigo actualizando artículos. En breve le tocará el turno al dedicado al Navigation Drawer.
Muchas gracias por su respuesta. Esperaré la actualización y darle mi enhorabuena su trabajo.
[…] los dos artículos anteriores aprendimos a hacer uso de la funcionalidad básica de una action bar y utilizar el nuevo componente Toolbar para conseguir el mismo comportamiento e incluso extenderlo […]
[…] defecto el accent color si lo hemos definido en el tema de la aplicación (más información en el artículo sobre la Action Bar) o el color de selección actual. Si queremos utilizar otro color debemos […]
[…] Actionbar / Appbar / Toolbar (I): Actionbar básica [Nuevo!] […]
Hola, ¿es posible eliminar la opción «Settings» de la barra? Es decir, que no haya ningún menú.
Hola, que pena no preguntar por algo relacionado con el tema en cuestión, pero veo que el foro no se usa mucho, quiero aprender a programar en android, ustedes creen que este curso es bueno para seguir e ir aprendiendo, esta lo suficientemente actualizado, que otros cursos online me podrian recomendar?, Gracias. Saludo.
Por si alguien tiene este error:
Error:Execution failed for task ‘:AppName:dexDebug’.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process ‘command ‘C:\Program Files\Java\jdk1.8.0_51\bin\java.exe» finished with non-zero exit value 2
He tenido que añadir al Gradle para importar el appcompat un exclude, quedandose así:
compile (‘com.android.support:appcompat-v7:22.1.1’)
{
exclude module: ‘support-v4’
}
Un saludo y gracias por el tutorial!
[…] por lo que este menú podemos definirlo de forma análoga a como ya lo hicimos por ejemplo en el artículo dedicado a la action bar para definir el menú de overflow, aunque más adelante mostraremos alguna […]
Error «Top level is not completed» y «Valid xml must have a root tag»
Hola, primero felicitaros por vuestra labor!
No se como solucionar: al intentar personalizar el action bar, en style me arroja error de «top level element is not completed» y «valid xml document must have a root tag» en el tema «Theme.AppCompat.Light.DarkActionBar»
@color/primary
@color/primary_dark
@color/accent
Gracias, y saludos
Muy bueno el articulo. Bien explicado y actualizado a la fecha. Y ademas en español!!! Gracias por compartir
Muy bien explicado todo, me encantan estos tutoriales, gracias.
Buenas,
Necesitaba saber como usar el Bottom toolbar. Por más que he buscado no me queda claro :( y lo necesito para el PFC. Alguien me ayuda, por favor? Muchas gracias!! Saludos
Hola buenas, como puedo ocultar el action bar en la pantalla main?
Excelente! :)
[…] el artículo anterior vimos cómo incluir una action bar (o app bar) en nuestras aplicaciones haciendo uso de la […]
[…] los dos artículos anteriores aprendimos a hacer uso de la funcionalidad básica de una action bar y utilizar el nuevo componente Toolbar para conseguir el mismo comportamiento e incluso […]