Crear un menú lateral o Drawer en flutter para la navegación en nuestra app

- Andrés Cruz

In english

Por lo general, el navigation drawer se abre desde el lado izquierdo de la pantalla, pero también puede configurarlo para que se abra desde el lado derecho y ocupa un 70 por ciento de la pantalla, y para cerrarlo, simplemente puede deslizar o hacer clic fuera del drawer.

¿Qué es un menú lateral o Drawer y para qué sirve?

Un menú lateral es un elemento de la interfaz de usuario que se muestra en el costado de una aplicación y que muestra opciones de navegación o acciones secundarias muy usadado este tipo de elemento de interfaz en en el contexto de apps en Flutter o Material Design y Android en general. Se puede abrir deslizando el dedo o tocando un botón o icono, y desplaza el contenido principal de la aplicación para mostrar opciones adicionales. Los usuarios pueden interactuar con las opciones del menú para acceder a diferentes vistas o acciones; es muy usado para la navegación entre distintas páginas.

Un menú lateral o Navigation Drawer simplemente es un panel de navegación que se muestra desde el lado izquierdo o derecho generalmente al presionar un botón de tipo hamburguesa desde el AppBar o Toolbar y que por supuesto podemos implementar en nuestra aplicación en Flutter.

El objetivo de este menú es presentar un conjunto de opciones a nuestro usuario que consiste en funcionalidades que permite realizar la aplicación.

¿Cómo crear un menú lateral?

Empleando Dart específicamente el framework de Flutter lo podemos crear fácilmente en nuestras aplicaciones empleando un widget que nos permite crear dicho componente y lo podemos atar fácilmente a un Scaffold mediante una propiedad llamada drawer.

Creando el Drawer

Aquí tienes que comenzar con lo típico, crear un proyecto limpio en Flutter con Android Studio o Visual Studio Code, quitar el código inicial y creamos un Scaffold:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter NavBar',
      ),
      home: Scaffold(
        appBar: AppBar(title: Text("Menu Lateral"),),
        drawer: CustomDrawer.getDrawer(),
      )
    );
  }
}

Vamos a conocer como podemos crear un Drawer o menú lateral en Flutter al igual que hicimos en Android en una entrada anterior en la cual creamos un menú lateral en Android; vamos a dar toda la implementación del código y luego iremos analizando el código en detalle:

Recuerda que un menú lateral es solo un panel vertical en la cual podemos colocar una colección de elementos que en nuestro caso sería una colección de ítems uno apilado debajo de otro; por lo tanto el Column nos viene perfecto aquí para apilar multitud de widgets para nuestra cabecera y opciones:

 class DrawerItem {
  String title;
  IconData icon;
  DrawerItem(this.title, this.icon);
}
 
class CustomDrawer {
 
  static int selectedDrawerIndex = 1;
 
  static final _drawerItems = [
    DrawerItem("Perfil", Icons.person),
    DrawerItem("Ver eventos", Icons.access_alarm),
    DrawerItem("Crear eventos", Icons.add_alarm),
    DrawerItem("Ver consejos", Icons.web),
    DrawerItem("Aviso legal", Icons.info)
  ];
 
  static _onTapDrawer(int itemPos, BuildContext context){
    Navigator.pop(context); // cerramos el drawer
    selectedDrawerIndex = itemPos;
  }
 
  static Widget getDrawer(BuildContext context) {
    final prefs = new UserPreferences();
    List<Widget> drawerOptions = [];
    // armamos los items del menu
    for (var i = 0; i < _drawerItems.length; i++) {
      var d = _drawerItems[i];
      drawerOptions.add(new ListTile(
        leading: new Icon(d.icon),
        title: new Text(d.title),
        selected: i == selectedDrawerIndex,
        onTap: () => _onTapDrawer(i, context),
      ));
    }
 
    // menu lateral
    return Drawer(
      child: Column(
        children: <Widget>[
          UserAccountsDrawerHeader(
              accountName: Text(prefs.name), accountEmail: Text(prefs.email)),
          Column(children: drawerOptions)
        ],
      ),
    );
  }
}

En términos generales, antes de entrar al detalle de todo el código, la app fue creada para ser consumida mediante métodos estáticos; Es decir, esto es una clase aparte que puedes consumir desde tus páginas en Flutter mediante en método de getDrawer() tal cual hacemos en nuestro curso de:

Items para el menú lateral

Para facilitar el proceso de creación de los ítems o las opciones del menú lateral y tener todo mejor organizado, creamos una clase auxiliar llamada _DrawerItem con los elementos de los cuales van a constar nuestro ítem de menú; para nuestro ejemplo, tiene lo usual, un título o nombre para el ítem y un ícono asociado, pero tu podrías personalizarlo aún más y colocar otros elementos como el color; como puedes ver, esta clase es privada, la razón, es que solamente nos interesa emplearla en la clase que se encarga de definir el panel vertical o menú lateral.

Y desde el código anterior también puedes ver que tenemos un array con los ítems del menú que emplean la clase que definimos y explicamos anteriormente.

Pero no podemos procesar un array de clases como tal, recuerda que todo en Flutter es un widget y un menú lateral no es la excepción, así que esta lista que tenemos definida como base o hardcode en nuestra función de build la podrías traer por ejemplo de una Rest Api.

Y pasamos esta lista a una Lista de widgets de tipo ListTile que emplearemos a posterior.

Mapear la lista de objetos de opciones a una lista de widgets

Lo siguiente que tenemos en la lista es mapear nuestra lista, es decir, tenemos una lista de objetos, pero drawerItems pero nosotros necesitamos es una lista de widgets; existen muchas formas en las cuales podemos hacer esto, pero la más interesante es emplear el método map que nos permite mapear de un tipo de dato a otro; tal cual puedes ver en la implementación, variamos de una lista de objetos a una lista de widgets; el punto interesante aquí es que la función de map implementa una función anónima en la cual podemos hacer cualquier clase de operación para convertir nuestro ítem inicial a otro tipo de objetos que en este caso sería un widget que a la final vendrá siendo nuestra lista de widgets; ya que la función map la podemos asignar a otro objeto y luego llamamos al método toList() para pasar de un mapa a una lista.

Crear el menú lateral: Drawer en Flutter

Cabecera o header del menú lateral

Ahora, ya con la data básica definida y lista para usar, creamos nuestro menú lateral, para eso hacemos uso del Scaffold como elemento raíz de nuestra app y su propiedad llamada drawer en el cual le podemos pasar un widget que será nuestro menú lateral Drawer; este menú lateral recibe un child como viene siendo usual en este tipo de componentes y luego le definimos un Column, porque vamos a definir una lista de elementos o widgets; lo primero que colocamos será un UserAccountsDrawerHeader que es un widget para definir una cabecera, así de fácil la famosa cabecera para definir elementos como la imagen del perfil, nombre de usuario o cuenta, email entre otros aspectos que puedes revisar.

Evento tap y navegación

Luego de la cabecera del Drawer, le pasamos nuestro listado de opciones, así de simple, lo que hicimos en el bloque anterior todo lo tenemos en una función que se lo pasamos de una a nuestro menú lateral y listo; como puedes notar, cada ítem del menú puede implementar un evento tap el cual lo tenemos definido pasando el index del elemento tocado; y de aquí nos viene perfecto el widget ListTile que permite definir, textos, íconos y el evento tap.

Otro widget opcional en esta implementación sería el de ConstrainedBox que nos permite definir una caja con unas dimensiones máximas o mínimas, es una especie de contenedor responsive con extremos; puedes buscar más información de la misma en la documentación oficial.

Otro punto importante que todavía no hemos visto y vamos a tratar en otra entrada, es la navegación entre pantallas que es un tema primordial y que sin ella las opciones de nuestro menú lateral servirán para bastante poco.

Pero con esto tenemos nuestro menú lateral implementado y listo para hacer lo que desees hacer.

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy