Cómo codificar un Navigation Drawer para Android App
Spanish (Español) translation by Kelly Gianella (you can also view the original English article)



El equipo de diseño de materiales de Google define la funcionalidad de un navigation drawer en Android de la siguiente manera:
El navigation drawe se desliza desde la izquierda y contiene los destinos de navegación de la aplicación.
Un ejemplo de una aplicación popular de Android que implementa el navigation drawer es la aplicación Bandeja de entrada de Google, que utiliza un navigation drawer para navegar a diferentes secciones de la aplicación. Puedes comprobarlo tú mismo descargando la aplicación Bandeja de entrada de la tienda Google Play, si aún no la tienes en tu dispositivo. A continuación, la captura de pantalla muestra la bandeja de entrada con el cajón de navegación abierto.



El usuario puede ver el cajón de navegación cuando desliza un dedo desde el borde izquierdo de la actividad. También pueden encontrarlo desde la actividad de inicio (el nivel superior de la aplicación), tocando el icono de la aplicación (también conocido como el menú "hamburguesa") en la barra de acciones.
Ten en cuenta que si tienes muchos destinos diferentes (por ejemplo, más de seis) en tu aplicación, se recomienda que uses un navigation drawer.
En esta publicación, aprenderás a mostrar elementos de navegación dentro de un navigation drawer en Android. Veremos cómo usar la API DrawerLayout y NavigationView para realizar esta tarea. Para obtener más información, también aprenderás a usar la función de plantillas de Android Studio para poner en marcha rápidamente tu proyecto con un navigation drawer.
Puedes encontrar un proyecto de ejemplo (en Kotlin) para este tutorial en nuestro repositorio de GitHub para que puedas seguirlo fácilmente.
Prerrequisitos
Para poder seguir este tutorial, necesitarás:
- Android Studio 3.0 o superior
- Kotlin plugin 1.1.51 o superior
1. Crea un proyecto de Android Studio
Abre Android Studio y crea un nuevo proyecto (puedes llamarlo NavigationDrawerDemo) con una actividad vacía llamada MainActivity. Asegúrate de marcar también la casilla Incluir soporte para Kotlin.



2. Agrega el DrawerLayout y NavigationView
Para empezar a utilizar DrawerLayout y NavigationView en tu proyecto, necesitarás importar el soporte de diseño y también el artefacto de soporte de Android. Así que añádelos al archivo build.gradle de tu módulo para importarlos.
1 |
dependencies { |
2 |
implementation 'com.android.support:design:27.0.2' |
3 |
implementation 'com.android.support:support-v4:27.0.2' |
4 |
}
|
Además, incluye tanto el widget DrawerLayout como el widget NavigationView en tu archivo res/layout/activlty_main.xml.
1 |
<?xml version="1.0" encoding="utf-8"?>
|
2 |
<android.support.v4.widget.DrawerLayout
|
3 |
xmlns:android="https://schemas.android.com/apk/res/android" |
4 |
xmlns:app="http://schemas.android.com/apk/res-auto" |
5 |
xmlns:tools="http://schemas.android.com/tools" |
6 |
android:id="@+id/drawer_layout" |
7 |
android:layout_width="match_parent" |
8 |
android:layout_height="match_parent" |
9 |
tools:openDrawer="start"> |
10 |
|
11 |
<include
|
12 |
layout="@layout/app_bar_main" |
13 |
android:layout_width="match_parent" |
14 |
android:layout_height="match_parent" /> |
15 |
|
16 |
<android.support.design.widget.NavigationView
|
17 |
android:id="@+id/nav_view" |
18 |
android:layout_width="wrap_content" |
19 |
android:layout_height="match_parent" |
20 |
android:layout_gravity="start" |
21 |
app:headerLayout="@layout/nav_header_main" |
22 |
app:menu="@menu/activity_main_drawer" /> |
23 |
|
24 |
</android.support.v4.widget.DrawerLayout>
|
Aquí creamos un widget DrawerLayout con el id drawer_layout. La propiedad tools:openDrawer se utiliza para mostrar el navigation drawer cuando el diseño XML está abierto en la vista de diseño de Android Studio.
La documentación oficial dice lo siguiente sobre DrawerLayout:
DrawerLayout actúa como un contenedor de nivel superior para el contenido de la ventana que permite que las vistas interactivas del "drawer" se extraigan de uno o ambos bordes verticales de la ventana.
Después de agregar el widget DrawerLayout, incluimos un diseño secundario que apunta a @layout / app_bar_main.
Aquí está mi archivo de recursos app_bar_main.xml. Este archivo simplemente tiene un CoordinatorLayout, un AppBarLayout, y un widget Toolbar.
1 |
<?xml version="1.0" encoding="utf-8"?>
|
2 |
<android.support.design.widget.CoordinatorLayout
|
3 |
xmlns:android="http://schemas.android.com/apk/res/android" |
4 |
xmlns:app="http://schemas.android.com/apk/res-auto" |
5 |
xmlns:tools="http://schemas.android.com/tools" |
6 |
android:layout_width="match_parent" |
7 |
android:layout_height="match_parent" |
8 |
tools:context=".MainActivity"> |
9 |
|
10 |
<android.support.design.widget.AppBarLayout
|
11 |
android:layout_width="match_parent" |
12 |
android:layout_height="wrap_content" |
13 |
android:fitsSystemWindows="true" |
14 |
android:theme="@style/AppTheme.AppBarOverlay"> |
15 |
|
16 |
<android.support.v7.widget.Toolbar
|
17 |
android:id="@+id/toolbar_main" |
18 |
android:layout_width="match_parent" |
19 |
android:layout_height="?attr/actionBarSize" |
20 |
android:background="?attr/colorPrimary" |
21 |
app:layout_scrollFlags="scroll|enterAlways" |
22 |
app:popupTheme="@style/AppTheme.PopupOverlay" /> |
23 |
|
24 |
</android.support.design.widget.AppBarLayout>
|
25 |
</android.support.design.widget.CoordinatorLayout>
|
Finalmente, creamos un widget NavigationView. La documentación oficial dice lo siguiente sobre NavigationView:
NavigationView representa un menú de navegación estándar para la aplicación. El contenido del menú se puede rellenar con un archivo de recursos de menú.
En el widget XML NavigationView, puede ver que agregamos un atributo android:layout_gravity con el valor start. Esto se utiliza para colocar el drawer: deseas que el drawer salga de la izquierda o de la derecha (el inicio o el final en las versiones de la plataforma que admiten la dirección del diseño). En nuestro caso, el cajón saldrá por la izquierda.
También incluimos un atributo app:headerLayout que apunta a @layout/nav_header_main. Esto añadirá una View como cabecera del menú de navegación.
Aquí está mi archivo de recursos de diseño nav_header_main.xml:
1 |
<?xml version="1.0" encoding="utf-8"?>
|
2 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
3 |
android:id="@+id/nav_header" |
4 |
android:layout_width="match_parent" |
5 |
android:layout_height="160dp" |
6 |
android:background="@color/colorAccent" |
7 |
android:clickable="true" |
8 |
android:focusable="true" |
9 |
android:foreground="?attr/selectableItemBackgroundBorderless" |
10 |
android:gravity="bottom" |
11 |
android:orientation="vertical" |
12 |
android:padding="16dp" |
13 |
android:theme="@style/ThemeOverlay.AppCompat.Dark"> |
14 |
|
15 |
<ImageView
|
16 |
android:id="@+id/nav_header_imageView" |
17 |
android:layout_width="64dp" |
18 |
android:layout_height="64dp" |
19 |
android:src="@mipmap/ic_launcher" /> |
20 |
|
21 |
<TextView
|
22 |
android:id="@+id/nav_header_textView" |
23 |
android:layout_width="match_parent" |
24 |
android:layout_height="wrap_content" |
25 |
android:paddingTop="16dp" |
26 |
android:text="Chike Mgbemena" |
27 |
android:textAppearance="@style/TextAppearance.AppCompat.Body1" /> |
28 |
</LinearLayout>
|
Este archivo de diseño simplemente tiene un LinearLayout, un ImageView, y un TextView.



Para incluir los elementos de menú para el navigation drawer, podemos usar el atributo app:menu con un valor que apunta a un archivo de recursos de menú.
1 |
<android.support.design.widget.NavigationView
|
2 |
app:menu="@menu/activity_main_drawer" /> |
Aquí está el archivo de recursos de menú res/menu/activity_main_drawer.xml:
1 |
<?xml version="1.0" encoding="utf-8"?>
|
2 |
<menu xmlns:android="http://schemas.android.com/apk/res/android"> |
3 |
<group>
|
4 |
<item android:id="@+id/nav_item_one" |
5 |
android:icon="@drawable/ic_drafts_black_24dp" |
6 |
android:title="Item 1" /> |
7 |
<item android:id="@+id/nav_item_two" |
8 |
android:icon="@drawable/ic_drafts_black_24dp" |
9 |
android:title="Item 2" /> |
10 |
<item android:id="@+id/nav_item_three" |
11 |
android:icon="@drawable/ic_drafts_black_24dp" |
12 |
android:title="Item 3" /> |
13 |
</group>
|
14 |
|
15 |
<group android:id="@+id/group_menu"> |
16 |
<item android:id="@+id/nav_item_four" |
17 |
android:title="Item 4" /> |
18 |
<item android:id="@+id/nav_item_five" |
19 |
android:title="Item 5" /> |
20 |
</group>
|
21 |
|
22 |
<item android:title="Title 1"> |
23 |
<menu>
|
24 |
<item android:id="@+id/nav_item_six" |
25 |
android:icon="@drawable/ic_drafts_black_24dp" |
26 |
android:title="Item 6" /> |
27 |
<item android:id="@+id/nav_item_seven" |
28 |
android:icon="@drawable/ic_drafts_black_24dp" |
29 |
android:title="Item 7" /> |
30 |
</menu>
|
31 |
</item>
|
32 |
</menu>
|
Aquí hemos definido un menú utilizando el <menu>que sirve como un contenedor para los elementos de menú. Un <item> crea un MenuItem, que representa un solo elemento en un menú.
A continuación, definimos nuestro primer grupo de menús utilizando el <group> archivo. Un <group>sirve como un contenedor invisible para los <item> elementos de menú en nuestro caso. Cada uno de los elementos < item > tiene un id, un icono y un título. Ten en cuenta que se dibujará una línea horizontal al final de cada < grupo > para nosotros cuando se muestra en el navigation drawer.
Un <item> también puede contener un elemento anidado para crear un <menu> submenú, hicimos esto en nuestro último <item>. Observa que este último <item> tiene un título de propiedad .
Ten en cuenta que al mostrar los elementos de la lista de navegación de un recurso de menú, podríamos usar un ListView en su lugar. Pero, al configurar el navigation drawer con un recurso de menú, obtenemos el estilo de diseño de material en el navigation drawer de forma gratuita. Si usaste un ListView, tendrías que mantener la lista y también aplicarle estilo para cumplir con las especificaciones de diseño de material recomendadas para el navigation drawer.
3. Inicialización de componentes
A continuación, vamos a inicializar instancias de nuestro DrawerLayout y ActionBarDrawerToggle. La inicialización va a ocurrir dentro de onCreate() en MainActivity.kt.
1 |
import android.content.res.Configuration |
2 |
import android.os.Bundle |
3 |
import android.support.v4.widget.DrawerLayout |
4 |
import android.support.v7.app.ActionBarDrawerToggle |
5 |
import android.support.v7.app.AppCompatActivity |
6 |
import android.support.v7.widget.Toolbar |
7 |
import android.view.MenuItem |
8 |
|
9 |
class MainActivity : AppCompatActivity() { |
10 |
|
11 |
private lateinit var drawer: DrawerLayout |
12 |
private lateinit var toggle: ActionBarDrawerToggle |
13 |
|
14 |
override fun onCreate(savedInstanceState: Bundle?) { |
15 |
super.onCreate(savedInstanceState) |
16 |
setContentView(R.layout.activity_main) |
17 |
|
18 |
val toolbar: Toolbar = findViewById(R.id.toolbar_main) |
19 |
setSupportActionBar(toolbar) |
20 |
|
21 |
drawer = findViewById(R.id.drawer_layout) |
22 |
|
23 |
toggle = ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) |
24 |
drawer.addDrawerListener(toggle) |
25 |
supportActionBar?.setDisplayHomeAsUpEnabled(true) |
26 |
supportActionBar?.setHomeButtonEnabled(true) |
27 |
}
|
28 |
|
29 |
// ...
|
30 |
}
|
El ActionBarDrawerToggle configura el icono de la aplicación ubicado a la izquierda de la barra de acciones o la barra de herramientas para abrir y cerrar el cajón de navegación. Para poder crear una instancia de ActionBarDrawerToggle, tenemos que proporcionar los siguientes parámetros:
- un contexto padre, por ejemplo, en una
actividadse usaesto, mientras que en unfragmentose llama agetActivity() - una instancia del widget
DrawerLayoutpara vincular aActionbarde la actividad - El icono que se coloca encima del icono de la aplicación para indicar que hay un botón de alternancia
- Los recursos de cadena para las operaciones abierto y cerrado respectivamente (para accesibilidad)
Invocamos el método addDrawerListener() en un DrawerLayout para conectar un ActionBarDrawerToggle con un DrawerLayout.
Ten en cuenta que también habilitamos el icono de la aplicación a través de setHomeButtonEnabled() y lo habilitamos para la navegación "ascendente" a través de setDisplayHomeAsUpEnabled().
Luego reenviamos los métodos de devolución de llamada de actividad onPostCreate(), onConfigurationChanged() y onOptionsItemSelected() al conmutador:
1 |
class MainActivity : AppCompatActivity() { |
2 |
|
3 |
// ...
|
4 |
|
5 |
override fun onPostCreate(savedInstanceState: Bundle?) { |
6 |
super.onPostCreate(savedInstanceState) |
7 |
toggle.syncState() |
8 |
}
|
9 |
|
10 |
override fun onConfigurationChanged(newConfig: Configuration?) { |
11 |
super.onConfigurationChanged(newConfig) |
12 |
toggle.onConfigurationChanged(newConfig) |
13 |
}
|
14 |
|
15 |
override fun onOptionsItemSelected(item: MenuItem?): Boolean { |
16 |
if (toggle.onOptionsItemSelected(item)) { |
17 |
return true |
18 |
}
|
19 |
return super.onOptionsItemSelected(item) |
20 |
}
|
21 |
}
|
Esto es lo que hace syncState(), según la documentación oficial:
Sincroniza el estado del indicador del drawer/funcionamiento vinculado con el DrawerLayout ... Esto debe ser llamado desde el métodoonPostCreatede tuActividadpara sincronizar después de que el estado de la instancia del DrawerLayout haya sido restaurado, y en cualquier otro momento cuando el estado pueda haber divergido de tal manera que el ActionBarDrawerToggle no haya sido notificado. (Por ejemplo, si dejas de reenviar los eventos de drawer apropiados durante un período de tiempo).
4. Probando la App
¡En este punto, podemos ejecutar la aplicación!



Como puedes ver, al iniciar la aplicación se mostrará el icono del navigation drawer "hamburguesa" en la barra de acciones. Intente tocar el icono de esta aplicación para abrir el drawer. Además, al hacer clic en los elementos del cajón de navegación no hará nada, vamos a manejar esa parte en la siguiente sección.
5. Controlar los eventos con un clic
Ahora, veamos cómo controlar los eventos, para cada uno de los elementos en el navigation drawer. Ten en cuenta que al hacer clic en cualquier elemento se supone que te llevará a una nueva actividad o fragmento, es por eso que se llama un cajón de navegación!
En primer lugar, la actividad debe implementar NavigationView.OnNavigationItemSelectedListener.
1 |
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener { |
2 |
// ...
|
3 |
}
|
Al implementar este contrato o interfaz, ahora debemos reemplazar el único método: onNavigationItemSelected().
1 |
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener { |
2 |
|
3 |
// ...
|
4 |
|
5 |
override fun onNavigationItemSelected(item: MenuItem): Boolean { |
6 |
|
7 |
when (item.itemId) { |
8 |
R.id.nav_item_one -> Toast.makeText(this, "Clicked item one", Toast.LENGTH_SHORT).show() |
9 |
R.id.nav_item_two -> Toast.makeText(this, "Clicked item two", Toast.LENGTH_SHORT).show() |
10 |
R.id.nav_item_three -> Toast.makeText(this, "Clicked item three", Toast.LENGTH_SHORT).show() |
11 |
R.id.nav_item_four -> Toast.makeText(this, "Clicked item four", Toast.LENGTH_SHORT).show() |
12 |
}
|
13 |
return true |
14 |
}
|
15 |
}
|
Este método se invoca cuando se selecciona un elemento en el menú de navegación. Usamos la expresión cuando para realizar diferentes acciones en función del elemento de menú en el que se hizo clic: los identificadores de elemento de menú sirven como constantes para la expresión cuando.
A continuación, tenemos que iniciar nuestro NavigationView y establecer este detector dentro de onCreate() de nuestra actividad.
1 |
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener { |
2 |
// ...
|
3 |
override fun onCreate(savedInstanceState: Bundle?) { |
4 |
// ...
|
5 |
val navigationView: NavigationView = findViewById(R.id.nav_view) |
6 |
navigationView.setNavigationItemSelectedListener(this) |
7 |
// ...
|
8 |
}
|
9 |
// ...
|
¡Vuelve a ejecutar tu proyecto!



Al hacer clic en algunos elementos, se muestra un mensaje del sistema, justo lo que esperábamos. Pero recuerda que al hacer clic en un elemento debe llevar al usuario a una nueva actividad o fragmento (ignoramos esto aquí por la brevedad).
Notarás que cuando haces clic en un elemento, el cajón todavía permanece. Sería mejor que cerraras automáticamente cada vez que se hiciera clic en un elemento. Veamos cómo hacerlo.
1 |
override fun onNavigationItemSelected(item: MenuItem): Boolean { |
2 |
|
3 |
when (item.itemId) { |
4 |
R.id.nav_item_one -> Toast.makeText(this, "Clicked item one", Toast.LENGTH_SHORT).show() |
5 |
R.id.nav_item_two -> Toast.makeText(this, "Clicked item two", Toast.LENGTH_SHORT).show() |
6 |
R.id.nav_item_three -> Toast.makeText(this, "Clicked item three", Toast.LENGTH_SHORT).show() |
7 |
R.id.nav_item_four -> Toast.makeText(this, "Clicked item four", Toast.LENGTH_SHORT).show() |
8 |
}
|
9 |
drawer.closeDrawer(GravityCompat.START) |
10 |
return true |
11 |
}
|
Para cerrar el cajón después de que hayas hecho clic en un vínculo, simplemente invoque closeDrawer() en una instancia de DrawerLayout y pase GravityCompat.START al método.
¡Realiza el proyecto una vez más y observa el resultado!
6. Manejo del botón Atrás presionado
Cuando el cajón está abierto, sería una mejor experiencia de usuario no cerrar la actividad de inicio si se presiona el botón Atrás. Esta es la forma en que funcionan las aplicaciones populares como la aplicación Bandeja de entrada de Google.
Por lo tanto, cuando el cajón está abierto y se presiona el botón Atrás, solo cierra el cajón en lugar de la actividad actual de inicio. A continuación, si el usuario vuelve a presionar el botón Atrás, se debe cerrar la actividad principal.
Así es como podemos lograr esto:
1 |
override fun onBackPressed() { |
2 |
if (drawer.isDrawerOpen(GravityCompat.START)) { |
3 |
drawer.closeDrawer(GravityCompat.START) |
4 |
} else { |
5 |
super.onBackPressed() |
6 |
}
|
7 |
}
|
¡Vuelve a realizar el proyecto y pruébalo!
7. Bono: Uso de plantillas de Android Studio
Ahora que has aprendido sobre las API involucradas para crear un cajón de navegación, te mostraré un acceso directo que incrementa la rapidez. Simplemente puedes usar una plantilla en lugar de codificar una actividad de cajón de navegación desde cero.
Android Studio proporciona plantillas de código que siguen las mejores prácticas de diseño y desarrollo de Android. Estas plantillas de código existentes (disponibles en Java y Kotlin) pueden ayudarte a poner en marcha rápidamente tu proyecto. Una de estas plantillas se puede utilizar para crear una actividad de cajón de navegación.
Te mostraré cómo usar esta práctica función en Android Studio.
Para un nuevo proyecto, Android Studio.



Escribe el nombre de la aplicación y haz clic en el botón Siguiente.
Puedes dejar los valores predeterminados tal como están en el cuadro de diálogo Dispositivos Android de destino. Haga clic de nuevo en el botón Siguiente.



En el cuadro de diálogo Agregar una actividad al móvil, desplázate hacia abajo y selecciona Actividad del Navigation Drawer. Haga clic en el botón Siguiente después de eso.



En el último cuadro de diálogo, puedes cambiar el nombre de la actividad, el nombre del diseño o el título si lo desea. Por último, haga clic en el botón Finalizar para aceptar todas las configuraciones.
Android Studio ahora nos ha ayudado a crear un proyecto con una actividad de navigation drawer. ¡Genial!
Se recomienda encarecidamente explorar el código generado.
También puedes usar plantillas para un proyecto de Android Studio ya existente. Simplemente ve a Archivo> Nuevo > Actividad > Actividad de Navigation Drawer



Las plantillas que vienen incluidas con Android Studio son buenas para diseños simples y para crear aplicaciones básicas, pero si deseas poner en marcha tu aplicación aún más, puede considerar algunas de las plantillas de aplicaciones disponibles en Envato Market.
Son un gran ahorro de tiempo para los desarrolladores experimentados, ayudándoles a cortar el problema de crear una aplicación desde cero y enfocar sus talentos en lugar de eso en las partes únicas y personalizadas de la creación de una nueva aplicación.
Conclusión
En este tutorial, aprendiste a crear un navigation drawer en Android mediante la API DrawerLayout y NavigationView desde cero. También exploramos cómo usar fácil y rápidamente las plantillas de Android Studio para crear un navigation drawer.
Recomiendo encarecidamente revisar las directrices oficiales de diseño de material para los navigation drawers para aprender más sobre cómo diseñar y utilizar correctamente los navigation drawers en Android.
¡Para obtener más información sobre la codificación para Android, revisa algunos de nuestros otros cursos y tutoriales aquí en Envato Tuts+!


Android SDKCrea una aplicación de música con una plantilla de aplicación de AndroidChike Mgbemena

Android SDKSimplifica el desarrollo de aplicaciones para Android con AnkoAshraff Hathibelagal

Android SDKCrea una interfaz con pestañas de Material Design en una Android AppChike Mgbemena

Plantillas de AppLas mejores 15 plantillas de aplicaciones para Android de 2017Nona Blackman

Android SDKCodifica una Android App de galería de imágenes con GlideChike Mgbemena



