Creando un Navigation Drawer (menú lateral) en Android

22-10-2014 - Andrés Cruz

In english

El Navigation Drawer es un panel que se expande y contrae desde el lado izquierdo de la pantalla del dispositivo y muestra un menú de opciones de navegación de la aplicación; es posible mostrar el menú lateral aplicando un toque en el lado izquierdo de la pantalla y arrastrando hacia la derecha o tocando el icono de la aplicación ubicado en la barra de acciones.

El menú lateral o Drawer Layout resulta un elemento más visual y personalizable que el menú tradicional empleado desde las primeras versiones de Android.

menú tradicional en android

Creando un menú lateral

Desde que se creó esta entrada han actualizado varias cosas en lo que se refiere a la construcción de nuestro NavigationView han cambiado; ya no necesitamos un ListView para la creación de nuestro menú lateral si no empleamos otro componente conocido como NavigationView para tal fin:

Menú lateral final

Entonces, este primer bloque de contenido corresponde a indicar cómo podemos desarrollar nuestro Navigation Drawer que viene siendo uno de los componentes fundamentales junto con nuestro Navigation View para crear nuestro menú lateral; de igual manera la antigua entrada seguirá estando vigente y puedes ver el contenido dando clic aquí.

Trataremos el NavigationView como sinónimo de Navigation View al igual que ocurre con NavigationDrawer y Navigation Drawer.

Así que con todo esto aclarado, vamos a crear nuestro menú lateral; para ello lo primeros que debes hacer es crear un proyecto en Android Studio como explicamos en la entrada que hablamos sobre como emplear Android Studio y crear un proyecto.

Una vez que tengamos nuestro proyecto creado, nos vamos al layout de nuestra actividad; que en este ejemplo corresponde al activity_main y copiamos el siguiente código:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:fitsSystemWindows="true">


    <android.support.design.widget.NavigationView
            android:id="@+id/navView"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:menu="@menu/menu"
            app:headerLayout="@layout/nav_header"
            android:fitsSystemWindows="true">

    </android.support.design.widget.NavigationView>

</android.support.v4.widget.DrawerLayout>

Como puedes ver, nuestro menú lateral consta de dos partes, el primero de ellos es el DrawerLayout no es más que un contenedor y no solo esto, es el Top de los contenedores, lo que significa que no puede ser contenido por ningún otro elemento sino tiene que estar en lo más alto de nuestra vista; aquí se encuentra lo que es el contenido de nuestra vista como botones, imágenes y por supuesto nuestro menú lateral, que se encuentra definido por elNavigationView.

Entonces en resumen, tenemos un contenedor llamado Drawer Layout y un menú que es contenido dentro del mismo con Navigation View.

Propiedades del menú lateral

Si analizamos el código anterior, verás que hay algunas propiedades importantes; entre ellas está la de android:fitsSystemWindows establecida en true; esta propiedad permite que el deslizamiento del nuestro menú lateral se realice correctamente y no tenga conflicto con ningún otro componente del sistema como la status bar.

También en nuestro Navigation View estamos definiendo un menú, o mejor dicho, una referencia a nuestro menú, que luce de la siguiente forma:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:title="Opción 1"
          android:icon="@drawable/ic_android"
          android:id="@+id/op1"></item>
    <item android:title="Opción 2"
          android:icon="@drawable/ic_android"
          android:id="@+id/op2"></item>
    <item android:title="Opción 3"
          android:icon="@drawable/ic_attach_file"
          android:id="@+id/op3"></item>
</menu>

Cómo ves, los menús definen una propiedad para indicar el título o el nombre de la opción de nuestro menú android:title y también especifica un icono android:icon.

Definir un header o cabecera

Y también definimos la propiedad app:headerLayout, que es opcional y permite indicar otro layout con el contenido de nuestra cabecera; aquí al ser otro layout podemos diseñar lo que queramos aunque generalmente se estila por algo sencillo, como una imagen del avatar de la persona y un identificador a la misma, su nombre, generalmente; en nuestro caso, vamos a emplear el siguiente XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="200dp"
              android:orientation="vertical"
              android:background="@drawable/nav_drawer_header"
              android:padding="16dp">
    <ImageView
            android:src="@mipmap/ic_launcher"
            android:layout_width="96dp"
            android:layout_gravity="center"
            android:layout_marginBottom="10dp"
            android:layout_marginTop="15dp"
            android:layout_height="96dp"/>

    <TextView android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:textColor="#FFF"
              android:gravity="center"
              android:text="Nombre"/>

    <TextView android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:textColor="#FFF"
              android:gravity="center"
              android:text="Nombre"/>
</LinearLayout>

Que se visualiza como:

Menú lateral header

El resto de las propiedades son de fácil entendimiento, ya viene siendo lo común en Android; por ejemplo para definir el ancho, el alto, la posición etc.

Con esto ya tenemos un menú lateral como el siguiente:

Menú lateral final segundo ejemplo

Bastante fácil en realidad, pero aún podemos modificar algunas cosas más.

Grupos en los ítems de nuestro menú lateral

Los agrupados son muy útiles cuando queremos tener opciones de un mismo tema o categoría en un mismo renglón; aunque a nivel visual no se logra una gran distinción (apenas una línea de separación), podemos agrupar esta sección y ocultarla o mostrarla bajo demanda programáticamente desde código Java o Kotlin:

    <group android:id="@+id/group1">
        <item android:title="Opción 3_1"
              android:icon="@drawable/ic_attach_file"
              android:id="@+id/op3_1"></item>
        <item android:title="Opción 3_2"
              android:icon="@drawable/ic_attach_file"
              android:id="@+id/op3_2"></item>
    </group>

Con este XML tenemos la siguiente presentación en nuestro NavigationDrawer:

Menú lateral final segundo ejemplo

Definir una opción como clickiable + título del grupo

Podemos indicar que solo una opción sea seleccionable en un momento dado con checkableBehavior indicado con el valor single y también podemos indicar un título para nuestra agrupación de la siguiente forma:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:title="Opción 1"
          android:icon="@drawable/ic_android"
          android:id="@+id/op1"></item>
    <item android:title="Opción 2"
          android:icon="@drawable/ic_android"
          android:id="@+id/op2"></item>
    <item android:title="Opción 3"
          android:icon="@drawable/ic_attach_file"
          android:id="@+id/op3"></item>

    <group android:id="@+id/group1">
        <item android:title="Opción 3_1"
              android:icon="@drawable/ic_attach_file"
              android:id="@+id/op3_1"></item>
        <item android:title="Opción 3_2"
              android:icon="@drawable/ic_attach_file"
              android:id="@+id/op3_2"></item>
    </group>

    <group android:id="@+id/group2"> android:checkableBehavior="single"
        <item
                android:id="@+id/navigation_subheader"
                android:title="Otro Grupo">
            <menu>
                <item
                        android:id="@+id/menu_opcion_1"
                        android:icon="@drawable/ic_attach_file"
                        android:title="Op 4.1"/>
                <item
                        android:id="@+id/menu_opcion_2"
                        android:icon="@drawable/ic_android"
                        android:title="Op 4.2"/>
            </menu>
        </item>
    </group>
</menu>

Con esto, obtenemos:

Menú lateral final segundo ejemplo

Creación del NavigationDrawer con los ListView

En esta primera entrada veremos cómo crear un menú lateral básico en Android:

1. Creando el Drawer Layout

Descargar Fuente en GitHub

Lo primero que debemos hacer es modificar la estructura del layout de la actividad en la cual deseamos que se muestre el menú lateral, añadimos el DrawerLayout como elemento raiz del layout principal de la actividad, además de un ListView para el menú lateral (Navigation Drawer). Si este era el layout con el contenido principal a mostrar:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

	<TextView
	    android:id="@+id/textView1"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:text="Hola Mundo!" />

</RelativeLayout/>

Al agregar el DrawerLayout y el ListView en el layout de la actividad, quedaría de la siguiente manera:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <RelativeLayout
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hola Mundo!" />

    </RelativeLayout>

    <ListView
        android:id="@+id/list_view"
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#007095"
        android:choiceMode="singleChoice"
        android:divider="#005875"
        android:dividerHeight="2dp" />
</android.support.v4.widget.DrawerLayout>

</RelativeLayout/>

Hay que colocar el contenido de la actividad dentro (como elemento hijo) del android.support.v4.widget.DrawerLayout.

Es posible especificar la dirección en donde se desee mostrar el menú empleando la propiedad layout_gravity:

  • layout_gravity="left":
menú lateral en android alineado a la izquierda
  • layout_gravity="right":
menú lateral en android alineado a la derecha

Se estila que la ubicación del menú lateral sea a la derecha.

2. Referenciando el Drawer Layout y el Navigation Drawer

Ya definido el layout de la actividad, el siguiente paso consiste en referenciar a los elementos con los cuales vamos trabajar; el ListView (Navigation Drawer: en donde se renderizará nuestro panel o menú lateral):

ListView listView = (ListView) findViewById(R.id.list_view);

Y el DrawerLayout, que representa el contenedor que permite la creación de vistas interactivas tipo Drawer:

DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

3. Definiendo el Adaptador (Adapter) con la estructura de opciones

Ya referenciados los elementos los elementos a utilizar en la Actividad, ahora es posible crear el menú de opciones a partir de una estructura de opciones como una List o Array y establecerlos en el ListView (Navigation Drawer) a través de un Adapter:

String[] opciones = { "Opción 1", "Opción 2", "Opción 3", "Opción 4" };

listView.setAdapter(new ArrayAdapter<String>(this,
		android.R.layout.simple_list_item_1, android.R.id.text1,
		opciones));

Es posible crear un Adapter personalizado para agregar otros elementos al menú como iconos, esto será explicado en otras entregas.

4. Configurando los eventos abrir y cerrar del menú lateral con el icono de la aplicación

Debemos sobreescribir e implementar los siguientes eventos y funciones si queremos:

  • Personalizar los eventos al pulsar cada opción: listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView
Mostrar u ocultar el panel o menú lateral: 	// Mostramos el botón en la barra de la aplicación
	//getActionBar().setDisplayHomeAsUpEnabled(true);

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			if (drawerLayout.isDrawerOpen(listView)) {
				drawerLayout.closeDrawers();
			} else {
				drawerLayout.openDrawer(listView);
			}
			return true;
		}

		return super.onOptionsItemSelected(item);
	}
        

Si ya has cumplido con los pasos anteriores, ya tendrás listo y a tu disposición un menú lateral o Navigation Drawer; en siguientes entregas veremos como personalizar el menú lateral agregando iconos, botones y cambiando el estilo del mismo; podrás encontrar el código fuente en nuestro repositorio de GitHub:

Descargar Fuente en GitHub


Andrés Cruz
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.

!Cursos a!

10$

En Udemy

Quedan 5 días!

Ver los cursos
¡Hazte afiliado en Gumroad!

!Cursos desde!

4$

En Academia

Ver los cursos

!Libros desde!

1$

Ver los libros
!Web Alojada en Hostinger!