Inicio Android Action Bar en Android (III): ActionBar Compat

Action Bar en Android (III): ActionBar Compat

por admin

Hace ya algún tiempo que hablamos en el curso sobre uno de los elementos visuales más representativos de las aplicaciones Android actuales, la Action Bar. Por aquel entonces comenté que Google había maltratado un poco a este componente al no incluirlo en la librería de compatibilidad android-support, lo que hacía que no fuera compatible con versiones de Android anteriores a la 3.0. Esto obligaba a recurrir a librerías externas como ActioBarSherlock para hacer nuestra aplicación compatible con cualquier versión de Android.

Y hemos tenido que esperar hasta hace unos días (julio de 2013) para ver por fin a la Action Bar debutar, de serie, en la librería de compatibilidad de Android. A partir de la revisión 18 de esta librería contamos con una versión de la Action Bar (conocida también como ActionBarCompat) compatible con cualquier versión Android a partir de la 2.1 (API 7). Y es de esto de lo que nos vamos a ocupar en este nuevo artículo, ya que aunque su uso es muy similar a lo que ya comentamos en el primer artículo sobre la Action Bar, son necesarios algunos pequeños cambios en el código y en la configuración del proyecto que justifican una nueva entrada para este tema.

Lo primero que tendremos que asegurar es que tenemos instalada la última versión de la librería de compatibilidad (Android Support Library). Para ello entramos al SDK Manager y actualizamos la librería a la última revisión (la 18 en el momento de escribir este artículo).

sdk-manager-android-support

Dado que el componente ActionBar incluido en la librería de compatibilidad contiene recursos no bastará con incluir el fichero jar de la librería en nuestro proyecto, sino que para utilizarlo habrá que importar previamente los fuentes como proyecto independiente en Eclipse y después utilizar dicho proyecto como una dependencia del nuestro. Para ello, el siguiente paso será esta importación de la librería. Los fuentes de la librería se encuentran en la siguiente ruta:

<ruta-sdk-android>\extras\android\support\v7\appcompat

Para importarlo como proyecto en Eclipse usaremos la opción «File/Import…», seleccionaremos “Existing Android Code Into Workspace”, indicaremos la ruta anterior y marcaremos la opción “Copy into workspace”.

import-existing-sources

Hecho esto ya tendríamos el proyecto de la librería correctamente importado en Eclipse:

appcompat-library-project

Son necesarios un par de pasos más para dejar correctamente configurado el proyecto de la librería. Entramos en las propiedades del proyecto, accedemos a la sección «Java Build Path» y después a la solapa “Order and Export“. En esta vista marcamos las dos librerías “android-support-v4.jar” y “android-support-v7-appcompat.jar” y desmarcamos “Android Dependencies”, quedando de la siguiente forma:

appcompat-build-path

Aceptamos todo y ya tendríamos preparada la librería de compatibilidad para poder añadirla a nuestro proyecto, que será lo siguiente que vamos a crear.

Crearemos nuestro proyecto como siempre hemos hecho: «File/New/Project…/Android Application Project» y seguiremos el asistente con la precaución de seleccionar como «Minimum Required SDK» una versión de Android anterior a la 3.0, para poder probar que efectivamente funciona nuestra Action Bar sobre esas versiones. En mi caso he seleccionado como versión de compilación la 4.2, como versión mínima la 2.2, y he llamado al proyecto «android-abcompat», el resto de opciones por defecto.

Accedemos ahora a las propiedades del nuevo proyecto, y después a la sección «Android». Aquí vamos a añadir la referencia a la librería de compatibilidad que hemos importado y preparado antes como proyecto independiente. En la sección «Library» pulsamos «Add» y seleccionamos el proyecto importado antes (android-support-v7-appcompat). Finalmente aceptamos y ya tenemos todo configurado para empezar a hacer uso de la action bar.

add-library

Más temas a tener en cuenta. Tendremos que sustituir (o extender) el tema visual utilizado en la aplicación por alguno de los definidos específicamente para la librería de compatibilidad:

  • Theme.AppCompat
  • Theme.AppCompat.Light
  • Theme.AppCompat.Light.DarkActionBar

En mi caso voy a utilizar el último de ellos. Modificaremos para ello nuestro fichero AndroidManifest.xml indicando el nuevo tema a utilizar en el atributo android:theme del elemento <application> (aunque también se puede definir a nivel de actividades).

...
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.AppCompat.Light.DarkActionBar" >
        <activity
            android:name="net.sgoliver.android.abcompat.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
...

Tenemos que modificar también la clase de la que heredan nuestras actividades, sustituyendo la clase Activity por la nueva clase ActionBarActivity de la librería android-support.

...
import android.support.v7.app.ActionBarActivity;

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	//...
}

Por último, la forma de añadir las opciones a la action bar no cambia, continúa siendo mediante la definición de menús XML (encontrarás más información en el artículo original del curso sobre la Action Bar). Pero sí varía un poco la forma en que debemos establecer algunos atributos de los menús.

Dado que en versiones anteriores a Android 3.0 no existían los atributos de los menús destinados a definir la funcionalidad de la action bar, por ejemplo el atributo android:showAsAction, no podemos utilizarlos libremente ahora que queremos que nuestra aplicación funcione sobre dichas versiones. Para solucionar esto lo que haremos será utilizar dichos atributos indicando un espacio de nombres personalizado, que definiremos en el elemento <menu> y posteriormente usaremos en los elementos <item>. Veamos cómo.

Definiremos el nuevo espacio de nombres en el elemento <menu> añadiendo un nuevo atributo de esta forma:

xmlns:nombre_del_nuevo_espacio_de_nombres=»http://schemas.android.com/apk/res-auto»

Podemos utilizar el nombre que queramos, yo por ejemplo usaré «sgoliver»:

xmlns:sgoliver=»http://schemas.android.com/apk/res-auto»

Posteriormente, en los elementos <item> del menú precederemos los atributos específicos de la action bar con este nuevo espacio de nombres (namespace).

En mi caso, he añadido dos acciones al menú, una de ellas (settings) que quiero que aparezca siempre en el menú de overflow, y la segunda (search) que quiero que aparezca como botón de acción si hay espacio para ella. De esta forma, la definición completa de mi menú quedaría de la siguiente forma:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:sgoliver="http://schemas.android.com/apk/res-auto" >

    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        sgoliver:showAsAction="never"
        android:title="@string/action_settings"/>

    <item
        android:id="@+id/action_search"
        android:orderInCategory="100"
        sgoliver:showAsAction="ifRoom"
        android:icon="@drawable/ic_action_search"
        android:title="@string/action_search"/>
</menu>

Como puede verse en el código anterior, al margen de la definición del nuevo espacio de nombres y de la utilización del atributo showAsAction asociado a él, el resto del código es exactamente igual que el que ya vimos en el artículo original sobre la action bar.

Por último, para responder a las pulsaciones sobre las distintas acciones que hemos incluido en la action bar podemos seguir utilizando el evento onOptionsItemSelected, en el que dependiendo del ID de la opción pulsada ejecutaremos las acciones que corresponda. En mi caso voy simplemente a mostrar un toast con la opción seleccionada:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
	switch(item.getItemId())
	{
		case R.id.action_settings:
			Toast.makeText(this, "Settings", Toast.LENGTH_SHORT).show();;
			break;
		case R.id.action_search:
			Toast.makeText(this, "Search", Toast.LENGTH_SHORT).show();
			break;
		default:
			return super.onOptionsItemSelected(item);
	}

	return true;
}

Llegados a este punto ya podemos ejecutar nuestro proyecto en el emulador para ver que todo funciona correctamente. En primer lugar lo vamos a hacer sobre un AVD con Android 4.2. Podemos ver cómo no existe ninguna diferencia, ni en aspecto ni en comportamiento, con la action bar tradicional.

demo-android-4

Ejecutamos ahora sobre Android 2.2 y esto es lo que nos aparece:

demo-android-2-p1

Todo parece correcto, salvo porque no aparece el menú de overflow ¿dónde están las opciones que hemos configurado para que aparezcan en el menú de la action bar? Pues siguen presentes, pero no en el mismo lugar. Android establece que si el dispositivo tiene un botón físico de Menú, el botón de overflow desaparece y se sustituye por un menú tradicional que aparece en la zona inferior cuando se pulsa el botón Menú del dispositivo. Este será el caso de la mayoría de dispositivos que funcionen con Android 2.x. Si pulsamos el botón menú del emulador veremos como ahora sí aparece nuestra acción «Settings».

demo-android-2-p2

Y hasta aquí el artículo. Espero que hayan quedado claros los pasos necesarios para utilizar esta nueva versión de la Action Bar compatible con la mayoría de verisiones de Android. Todo sea por que más personas puedan disfrutar de nuestras aplicaciones en su totalidad.

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.

También te puede interesar

20 comentarios

Mentix 04/08/2013 - 1:32

Genial mejora de la interfaz, aunque desde hace un tiempo si podía observar ese comportamiento en el play store, era hora que lo liberaran para los desarrolladores.

Responder
JDiego 06/08/2013 - 10:53

Buenos días:

Muy buen tutorial.
Con esto se podrían poner temas personalizados como en la sherlockactionbar?

Responder
Klausus 10/08/2013 - 7:06

Hola esto me ha venido de perlas, aunque al principio me tube que estrujar el cerebro para poder conseguir hacerlo funcionar en AndroidStudio pero es bastante mas simple (el problema es la poca documentacion al respecto).

AndroidStudio aun le queda mucho desarrollo para llegar al nivel de Eclipse por desgracia…

Gracias ;D

Responder
Interfaz de Usuario en Android: Navigation Drawer | sgoliver.net blog 10/08/2013 - 11:38

[…] el artículo anterior hablamos sobre una de las últimas novedades del SDK de Android, la nueva versión de la Action Bar […]

Responder
Diana 12/08/2013 - 20:10

Hola a todos, tengo una duda de novata… a ver si alguien me pudiera ayudar. He seguido todos los pasos, y mi duda me surge a partir de que creo que no se puede eliminar el proyecto «android-support-v7-appcompat» una vez que ya se han incluido las librerías, es decir, ¿cuándo creamos nuestro proyecto tenemos que mantener el proyecto «android-support-v7-appcompat» para que el nuestro funcione?
¡Muchas gracias de antemano!
Saludos.

Responder
Ricardo 02/09/2013 - 2:48

Hola.

Como se establece el tema full screen (@android:style/Theme.NoTitleBar.Fullscreen) ahora que hay que heredar de los temas AppCompat. Toda mi aplicación funciona con este tema.

Gracias

Responder
David 10/09/2013 - 12:22

Comentar que esto no funciona si no está instalada la API 16. Desconozco si existe algún tipo de dependencia entre ambas APIs.

Saludos!

Responder
David 10/09/2013 - 13:25

En mi caso, tengo todo igual y no me funciona por este icono

android:icon=»@drawable/ic_action_search»

Para que me funcione tengo que poner este otro:

android:icon=»@drawable/abc_ic_search»

No entiendo por qué en este post funciona bien y yo tengo que cambiarlo. Tengo todos los ficheros exactamente igual.

Saludos!

Responder
Raul 24/09/2013 - 23:32

Consigo mostrar la ActionBar en Android 2.2 cambiando los Activity por ActionBarActivity pero, ¿como debo hacerlo en las pantallas del tipo ListActivity? ¿Y en la pantalla de Ajustes que es del tipo PreferenceActivity?
Gracias

Responder
edert0 27/09/2013 - 19:23

Hola,
tengo el mismo problema que Raul.
Alguien nos puede decir algo?
Gracias, y un saludo!

Responder
Manuel 14/11/2013 - 11:22

He seguido todos los pasos y a la hora de ejecutarlo, me da el siguiente error:

java.lang.NoSuchMethodError: es.example.actionbar.MainActivity.getActionBar

Que se refiere a la linea

ActionBar abar = getActionBar();

¿Me pueden ayudar?

Enhorabuena por los tutoriales, están geniales.

Gracias. Un saludo.

Responder
John 17/11/2013 - 20:17

Manuel, debes usar getSupportActionBar() puesto que este ejemplo usa la librería de compatibilidad android-support-v7-appcompat. Para agregar la librería puedes ver la respuesta más calificada a esta pregunta:
http://stackoverflow.com/questions/17903521/android-actionbar-how-to-add-supporting-library-v7-appcompat

Responder
Hernaldo 19/11/2013 - 18:40

En mi caso: No funcionaba nada me daba el error

Error: No resource found that matches the given name (at ‘theme’ with value ‘@style/Theme.AppCompat.Light.DarkActionBar’). AndroidManifest.xml

en la linea del manifiest:

android:theme=»@style/Theme.AppCompat.Light.DarkActionBar» >

asi que lo que hice fue:

Borre el «android-support-v7-appcompat» del package explorer.

Lo importe de nuevo, al importar marque «Copy into workspace” ya qu no lo había marcado.

Luego en Properties -> Android -> lo subí el Project build target de Android 2.2 a Android 4.1.2 tal como en la foto.

En las propiedades del mismo proyecto (android-support-v7-appcompat) en Java build path no tenia ningun .jar, asi que solo deschequie las Dependencias.

El proyecto que referencia a «android-support-v7-appcompat» en Propiedades -> Android lo agregue como librería, sin marcar «IsLibrary».
En Android -> Project build tarjet lo deje como 4.0.

Al final un «Project -> Clean» a los dos y funciono luego de 4 horas peliando

Responder
Hernaldo 19/11/2013 - 18:44

Me falto un punto, revisar en el proyecto que usa la librería:

en «Java Build Path» -> Order and Export -> deschequear las librerias jar si las hay

Responder
Gabriel 19/12/2013 - 17:32

Gracias, excelente tutorial, muy claro. Funciona bárbaro

Responder
Teresa 19/12/2013 - 20:50

A mi no me aparece el icono que luego despliegas y pone settings, lo tengo idéntico he añadido otro botón y me lo pone sin problemas, pero el icono ese de overflow y el settings no, alguien me sabría decir por qué puede ser por favor?

Gracias. Un saludo

Responder
daniel 15/04/2014 - 13:57

hola queria preguntarle como hago para cambiar el color de mi actionBar pero solo me sirve hasta la version 3.0 que sera y implemento la libreria v7

@style/MyActionBar
true
@color/gris

@color/amarillo
@style/MyActionBarTitleText

@color/gris

Responder
panshot 10/05/2014 - 3:51

muy bueno y util

Responder
fran 20/08/2015 - 21:40

Hola buenas a todos, tengo el siguiente problema y es que resulta que yo el actionBar no lo quiero poner en el main lo quiero poner en otra actividad, pero al ponerlo, y ejecutar el pograma al llamar al metodo «getActionBar();» me dice que es nulo , y sospecho que solo se puede poner en el activiti_main pero yo no quiero eso dado que en ese tengo el login y despues del login es cuando necesito esto , un saludo. Si alquién me puede ayudar lo agradeceria.

Responder

Dejar un comentario

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información. Aceptar Más Información

Política de Privacidad y Cookies