Android Navigation Drawer

Navigation Drawer is widely used now after Google officially support it in android support library. Apps like Gmail and Youtube also use this design, and it’s really more convinent to put navigation items in navigation drawer than in a Tab control, and this design will also make the visible size of your app much larger. I have used navigation drawer in the demo code for ExpandableListView here. It’s very simple, you can download and learn how we can use navigation drawer.

To use navigation drawer in your app, you just need the steps below:

  • first you need to declear DrawerLayout as the root container of you layout
  • the first child of DrawerLayout is the main container of your app, usually it’s a kind of viewGroup.
  • the second child of DrawerLayout is a ListView, which is used for place navigation items.

Below is a the layout we use in the demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<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">



<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->

< FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />



<!-- android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
The drawer is given a fixed width in dp and extends the full height of
the container. A solid background is used for contrast
with the content view. -->

<ExpandableListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#999999"
android:dividerHeight="1dp"
android:background="#ffffff"/>

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

After you declear this LayoutFile, you need to init your drawerLayout in the onCreate method of your MainActivity class. Simply like this:

1
2
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ExpandableListView) findViewById(R.id.left_drawer);


Of course you need to provide an adapter for your ListView to populate the drawer, and after all these steps above, you can have navigation drawer in your app, but there are something more you should know.

##DrawerLayout state
After your app is configured with navigation drawer, when user taps and holds on the edge of your screen, drawer will slide into the screen, as well as users use the slide gesture. Maybe sometimes you want to disable this, that is keep drawer closed all the time. The api also provide use three state:LOCK_MODE_LOCK_CLOSED, LOCK_MODE_LOCK_OPEN,LOCK_MODE_UNLOCK, you can use setDrawerLockMode to keep drawer closed all time or open all time.

##Listener for Drawer Events
In order to listen to events of navigation drawer, such Drawer open and Drawer Close, you need to add listener for your the DrawerLayout object, and Interface DrawerLayout.DrawerListener' is used for this. But you do not need to implement this interface yourself, android already provide us an convinent class calledActionBarDrawerToggle` which is used to implement recommended design for navigation drawers as google says

This class provides a handy way to tie together the functionality of DrawerLayout and the framework ActionBar to implement the recommended design for navigation drawers.
you need to read reference of this class to make it functional.

##Bug in DrawerLayout
when I use it, I also found one bug about DrawerLayout, when I use multiple finger to zoom my app, it will crash with the following stack

java.lang.ArrayIndexOutOfBoundsException android.support.v4.widget.ViewDragHelper.shouldInterceptTouchEvent(ViewDragHelper.java:1004) android.support.v4.widget.DrawerLayout.onInterceptTouchEvent(DrawerLayout.java:820) android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1909) android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2270) android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2010) android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2270) android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2010) android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2270) android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2010) android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2270) android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2010)

This is caused by an issue of DrawerLayout 60464, and you can find discuss and solution here.

Wish this will be helpful :)