Introduction

According to the official documentation, “The navigation drawer is a panel that displays the app’s main navigation options on the left edge of the screen.”. It is implemented in the Android Design Support Library in a component called NavigationView. When using it in a well designed app, it can make your app looks great and easy to use.

There are many great articles explaining how to implement Navigation Drawer from scratch, like this and this, so my goal here is not to show a step by step guide, but rather just to point out some implementation details I found interesting when I was learning this component. 

You can find here a complete demo project which implements all the features we will discuss on this article. You are more than welcome to use it the way you want. Also I tried to add some useful comments in the source-code that might help you to understand some further details. You will also find references for all articles I used while creating this article and the demo app.

So, let’s have some code.

Initial setup and XML files

In order to implement Navigation Drawer, we need to provide some XML files and declare some resources such as DrawerLayout, NavigationView, etc. For our example, they are: activity_main.xml, toolbar.xml and nav_header.xml resource files. nav_header.xml file provides a layout for the NavigationView_headerLayout resource in order to use a header for the NavigationView. Although this is not mandatory, we use it to show some profile information such as a photo and an email account. We also provide a menu XML file containing all the drawer menu options we want to use (menu/drawer_view.xml).

In the demo project you will find all those XML files and their usages into the Java code.

Note:  Since we are using a Toolbar as an ActionBar, we need first to change our AppTheme to use NoActionBar as the parent theme, otherwise we will get a java.lang.IllegalStateException exception.

Hamburger icon animation

If we want to add an animation to that little hamburger icon indicating when drawer is being opened and closed, we need to use the ActionBarDrawerToggle class. Also, when using the ActionBarDrawerToggle, we must call it during onPostCreate() and onConfigurationChanged()

Handling orientation changes

Keep the current selected drawer menu

In order to keep the current selected drawer menu item when screen is rotated, we need to hold a reference to its index whenever it is changed:

Then, save it on the onSaveInstanceState() and restore it on onRestoreInstanceState() method; after restore it, if index is greater than -1, we can get the corresponding menu item from the NavigationView and set it as selected:

Keep Navigation Drawer Menu Item State

If your NavigationView contains items which are not selectable, but rather they are used only to reflect an state (e.g.: connected to an external server) by showing different icons and  text based on that state, we can also use onSaveInstanceState() and onRestoreInstanceState() methods to save and restore those states. Then, after restore them, we just need to find the corresponding menu item and set the icon and the text properly:

Handling item click

Changing fragments

When the user clicks on certain menu items, sometimes is useful not to open a new activity, but only changes the current fragment. We can do it by finding the corresponding fragment for the item clicked and and replace it using FragmentManager. We can also change the app title to reflect the action user is doing. This snippet shows when user clicks on the Home menu option:

Starting a new activity

If, instead of changing the current fragment, you want to start a new activity when a drawer menu item is clicked (e.g.: to open a help activity), we simply call startActivity passing an intent that points to the desired activity. It is interesting to first close the drawer programmatically, otherwise when closing that new activity, the drawer will still be visible:      

It is a good practice to use ActionBar::setDisplayHomeAsUpEnabled(true) in the new activity, so that it will show a back narrow indicator which will bring user back to the previous activity.

Single selectable drawer menu item 

Depends on what you want to show, it is interesting to make some drawer menu items single selectable. To do so, just add all items you want to group inside the same group (in the menu XML file) and add “android:checkableBehavior=single” property to the group. Then, when we call MenuItem::setChecked(true) for an item, all the others will be unchecked automatically.

Adding information to the navigation header

If your app supports user login, it would be nice to have some information in the navigation header about the current user logged on, such as the user photo and an email account or even the user name. To do so, in the header XML file we can define an imageView and a textView views which will hold the user photo and the user email account information. For our example we are using an external library called CircleImageView to hold the image, which is pretty nice and easy to use. Now, during the drawer setup (or when a new user is logged on), we just set the user image and email account. If we want to react when some view is clicked (for example, open an email app when email view is clicked), just add an onClickListener listener to that view:

Custom navigation drawer menu item

Sometimes we need a different menu item such as a switch view instead the default item. To implement it we need to provide a custom XML layout and add it to the corresponding menu item. In our example we created the “action_view_switch.xml” which implements a SwitchCompact view. Then we added it to the “nav_drawer_notification_item” menu item by adding it to the actionLayout property:   

Then, to handle events for this component, add a listener during the drawer setup. In our case we will change the item icon based on the switch state:

Navigation drawer sliding

When using Navigation Drawer we can choose whether it will slide over the ActionBar or not. This is just a matter of the XML views positioning. For the former, we need to add our Toolbar inside the DrawerLayout; for the latter we first declare our Toolbar and then, right below it, we declare the DrawerLayout containing the container in which fragments will be loaded.

Note that Material Design guidelines state that Navigation Drawer should be above the Toolbar

 ActionBar above the DrawerLayout

Sliding Navigation Drawer over the ActionBar

Note: The demo app uses navigation drawer over the ActionBar.

Conclusion

Navigation Drawer is just one of many great Material Design implementations that we can find in the Design Support Library.

We showed some points we found interesting when using this component. We hope that by putting them all together in a single article, it can help those whose are not familiar with it. 

If you have questions, let a comment below.