Creating a Navigation Drawer (side menu) in Android

- Andrés Cruz

En español
Creating a Navigation Drawer (side menu) in Android

The Navigation Drawer is a panel that expands and collapses from the left side of the device screen and displays a menu of application navigation options; the side menu can be displayed by tapping on the left side of the screen and dragging to the right or by tapping the app icon located on the action bar.

The side menu or Drawer Layout is a more visual and customizable element than the traditional menu used since the first versions of Android.

menú tradicional en android

Creating a side menu

Since this entry was created several things have changed regarding the construction of our NavigationView; We no longer need a ListView for the creation of our side menu if we do not use another component known as NavigationView for this purpose:

Menú lateral final

So, this first block of content corresponds to indicating how we can develop our Navigation Drawer, which has been one of the fundamental components together with our Navigation View to create our side menu; In the same way, the old entry will continue to be valid and you can see the content by clicking here.

We'll treat NavigationView as a synonym for Navigation View just like NavigationDrawer and Navigation Drawer.

So with all this clarified, we are going to create our side menu; For this, the first thing you must do is create a project in Android Studio as we explained in the entry that we talked about how to use Android Studio and create a project.

Once we have our project created, we go to the layout of our activity; which in this example corresponds to activity_main and we copy the following code:

<?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>

As you can see, our side menu consists of two parts, the first one is the DrawerLayout, it is nothing more than a container and not only this, it is the Top of the containers, which means that it cannot be contained by any other element but it has to be at the top of our sight; Here is what the content of our view is like buttons, images and of course our side menu, which is defined by the NavigationView.

So in summary, we have a container called Drawer Layout and a menu that is contained within it with the Navigation View.

Side Menu Properties

If we analyze the previous code, you will see that there are some important properties; among them is android:fitsSystemWindows set to true; this property allows the sliding of our side menu to be carried out correctly and not conflict with any other system component such as the status bar.

Also in our Navigation View we are defining a menu, or rather, a reference to our menu, which looks like this:

<?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>

As you can see, menus define a property to indicate the title or the name of our menu option android:title and it also specifies an android:icon icon.

Define a header

And we also define the app:headerLayout property, which is optional and allows us to indicate another layout with the content of our header; Here, as it is another layout, we can design what we want, although it is generally styled by something simple, such as an image of the person's avatar and an identifier for it, its name, generally; In our case, we will use the following 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>

Which is displayed as:

Menú lateral header

The rest of the properties are easy to understand, it has already been common in Android; for example to define the width, height, position etc.

With this we already have a side menu like the following:

Menú lateral final segundo ejemplo

Pretty easy actually, but we can still tweak a few more things.

Groups in the items of our side menu

The grouped ones are very useful when we want to have options of the same subject or category in the same line; although at a visual level a great distinction is not achieved (barely a separating line), we can group this section and hide or show it on demand programmatically from Java or Kotlin code:

    <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>

With this XML we have the following presentation in our NavigationDrawer:

Menú lateral final segundo ejemplo

Define an option as clickiable + group title

We can indicate that only one option is selectable at a given time with checkableBehavior indicated with the value single and we can also indicate a title for our grouping as follows:

<?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>

With this, we get:

Menú lateral final segundo ejemplo

Creation of the NavigationDrawer with the ListView

In this first entry we will see how to create a basic side menu in Android:

1. Creando el Drawer Layout

GitHub

The first thing we must do is modify the layout structure of the activity in which we want the side menu to be displayed, we add the DrawerLayout as the root element of the main layout of the activity, as well as a ListView for the side menu (Navigation Drawer). If this was the layout with the main content to display:

<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/>

By adding the DrawerLayout and the ListView in the layout of the activity, it would look like this:

<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/>

You have to place the content of the activity inside (as a child element) of the android.support.v4.widget.DrawerLayout .

You can specify the direction in which you want to display the menu using the layout_gravity property:

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

It is customary for the location of the side menu to be on the right.

2. Referencing the Drawer Layout and the Navigation Drawer

Once the layout of the activity has been defined, the next step consists of referencing the elements with which we are going to work; the ListView (Navigation Drawer: where our panel or side menu will be rendered):

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

And the DrawerLayout, which represents the container that allows the creation of interactive Drawer-type views:

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

3. Defining the Adapter with the options structure

Once the elements to be used in the Activity have been referenced, it is now possible to create the options menu from an options structure such as a List or Array and establish them in the ListView (Navigation Drawer) through an 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));

It is possible to create a custom Adapter to add other menu items such as icons, this will be explained in other installments.

4. Configuring the open and close events of the side menu with the application icon

We must override and implement the following events and functions if we want to:

  • Customize the click events for each option: 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);
	}
        

If you have already completed the previous steps, you will already have a side menu or Navigation Drawer ready and at your disposal; In subsequent installments we will see how to customize the side menu by adding icons, buttons and changing its style; you can find the source code in our GitHub repository:

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.