codeofaninja
website

Android Navigation Drawer Example Source Code

Photo of Mike Dalisay
Modified Saturday, February 15, 2014
by - @ninjazhai
Note: The code is working but we are currently improving this article.

This is a step by step guide on how to create a navigation drawer for your Android app.


DOWNLOAD SOURCE CODE


First, create a new project File > New > Android Application Project > "NavigationDrawerExample"

Steps:

1. Change activity_main.xml to navigation drawer layout


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

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

    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#111"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp" />

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

2. Prepare MainActivity properties


private String[] mNavigationDrawerItemTitles;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;

3. res/values/strings.xml - put the drawer items array


<string-array name="navigation_drawer_items_array">
    <item>Create</item>
    <item>Read</item>
    <item>Help</item>
</string-array>

4. put inside MainActivity.java oncreate - initialize three properties


mNavigationDrawerItemTitles= getResources().getStringArray(R.array.navigation_drawer_items_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);

5. create res/layouts/listview_item_row.xml 

This is for list view inside navigation drawer. Right click res/layouts/ folder > New > File > Name it "listview_item_row.xml"

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?android:attr/activatedBackgroundIndicator"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
    android:padding="10dp" >

    <ImageView
        android:id="@+id/imageViewIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:paddingRight="10dp" />

    <TextView
        android:id="@+id/textViewName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@+id/imageViewIcon"
        android:paddingRight="10dp"
        android:text="Folder name here."
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        android:textColor="#ffffff" />

</RelativeLayout>


6. create an object for drawer item ObjectDrawerItem.java


File > New > Class > Name it "ObjectDrawerItem"

public class ObjectDrawerItem {

    public int icon;
    public String name;

    // Constructor.
    public ObjectDrawerItem(int icon, String name) {

        this.icon = icon;
        this.name = name;
    }
}

7. put nav drawer item icons in res/drawable-hdpi/


I have:
ic_action_copy.png
ic_action_refresh.png
ic_action_share.png

8. put inside oncreate - list the drawer items


ObjectDrawerItem[] drawerItem = new ObjectDrawerItem[3];

drawerItem[0] = new ObjectDrawerItem(R.drawable.ic_action_copy, "Create");
drawerItem[1] = new ObjectDrawerItem(R.drawable.ic_action_refresh, "Read");
drawerItem[2] = new ObjectDrawerItem(R.drawable.ic_action_share, "Help");

9. create the custom adapter DrawerItemCustomAdapter.java


public class DrawerItemCustomAdapter extends ArrayAdapter<ObjectDrawerItem> {

    Context mContext;
    int layoutResourceId;
    ObjectDrawerItem data[] = null;

    public DrawerItemCustomAdapter(Context mContext, int layoutResourceId, ObjectDrawerItem[] data) {

        super(mContext, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.mContext = mContext;
        this.data = data;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View listItem = convertView;

        LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
        listItem = inflater.inflate(layoutResourceId, parent, false);

        ImageView imageViewIcon = (ImageView) listItem.findViewById(R.id.imageViewIcon);
        TextView textViewName = (TextView) listItem.findViewById(R.id.textViewName);
       
        ObjectDrawerItem folder = data[position];

       
        imageViewIcon.setImageResource(folder.icon);
        textViewName.setText(folder.name);
       
        return listItem;
    }

}

10. pass the list of drawer items to DrawerItemCustomAdapter


This is to create the adapter - inside MainActivity.java oncreate

DrawerItemCustomAdapter adapter = new DrawerItemCustomAdapter(this, R.layout.listview_item_row, drawerItem);

11. set the adapter - oncreate


mDrawerList.setAdapter(adapter);

12. create the item click listener DrawerItemClickListener.java


private class DrawerItemClickListener implements ListView.OnItemClickListener {
   
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        selectItem(position);
    }
   
}

private void selectItem(int position) {
   
    Fragment fragment = null;
   
    switch (position) {
    case 0:
        fragment = new CreateFragment();
        break;
    case 1:
        fragment = new ReadFragment();
        break;
    case 2:
        fragment = new HelpFragment();
        break;

    default:
        break;
    }
   
    if (fragment != null) {
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        getActionBar().setTitle(mNavigationDrawerItemTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
       
    } else {
        Log.e("MainActivity", "Error in creating fragment");
    }
}

13. create the needed fragments and the views to inflate in res/layout/ 


(i.e. CreateFragment.java => res/layout/fragment_create.xml)

CreateFragment.java

public class CreateFragment extends Fragment {

    public CreateFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_create, container, false);

        return rootView;
    }

}


fragment_create.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/txtLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Create View"
        android:textSize="16dp" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/txtLabel"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:src="@drawable/ic_action_copy" />

</RelativeLayout>

14. set the item click listener - oncreate


...and  Inside MainActivity.java

mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

15. try to run - swipe your finger left to right - it works!


As of this stage, the app icon is useless to the nav drawer. It cannot trigger the nav drawer. This is what will be our next steps.

16. for app icon control for nav drawer, add new property on MainActivity


ActionBarDrawerToggle mDrawerToggle;

17. add ic_drawer.png in res/drawable-hdpi/


18. add open and close description in values/string/


<string name="drawer_open">Open navigation drawer</string>
<string name="drawer_close">Close navigation drawer</string>

19. Set properties for proper title display


private CharSequence mDrawerTitle;
private CharSequence mTitle;

..and inside onCreate, after setContentView

mTitle = mDrawerTitle = getTitle();

20. add the app icon control code inside MainActivity oncreate


mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(
        this,
        mDrawerLayout,
        R.drawable.ic_drawer, 
        R.string.drawer_open, 
        R.string.drawer_close 
        ) {
   
    /** Called when a drawer has settled in a completely closed state. */
    public void onDrawerClosed(View view) {
        super.onDrawerClosed(view);
        getActionBar().setTitle(mTitle);
    }

    /** Called when a drawer has settled in a completely open state. */
    public void onDrawerOpened(View drawerView) {
        super.onDrawerOpened(drawerView);
        getActionBar().setTitle(mDrawerTitle);
    }
};

mDrawerLayout.setDrawerListener(mDrawerToggle);

getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);

21. add onOptionsItemSelected() method


really needed to make app icon a toggle of nav drawer

@Override
public boolean onOptionsItemSelected(MenuItem item) {
   
   if (mDrawerToggle.onOptionsItemSelected(item)) {
       return true;
   }
  
   return super.onOptionsItemSelected(item);
}

22. Override setTitle() method


really needed for changing titles

@Override
public void setTitle(CharSequence title) {
    mTitle = title;
    getActionBar().setTitle(mTitle);
}

and then change this line

getActionBar().setTitle(mNavigationDrawerItemTitles[position]);

to this line

setTitle(mNavigationDrawerItemTitles[position]);

23. onPostCreate() method


 really needed to change the up caret icon before the app icon

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    mDrawerToggle.syncState();
}

Lower Android (2.2+) Version Compatibility


Android Navigation Drawer only works for Honeycomb and Up. To make it work with pre-honeycome devices, you should use the Android support library. Download it first using your SDK manager and then follow the step by step guide here.

More about the Navigation Drawer:
http://developer.android.com/training/implementing-navigation/nav-drawer.html

The Code of a Ninja Resources


For FREE programming tutorials, click the red button below and subscribe! :)
Thanks for the comments!
 
 
Fundamentals
"First do it, then do it right, then do it better."
~ Addy Osmani
"Talk is cheap. Show me the code."
~ Linus Torvalds
Let's Stay Connected!
g+ r
Android app on Google Play
© 2011-2014 The Code Of A Ninja. All rights reserved. Proudly Powered by Google Blogger. Images, logos, marks or names mentioned herein are the property of their respective owners.