Android : Navigation Drawer

A few days ago, i wrote a tutorial about creating a sliding menu using the SlidingMenu library. Since, Google has introduced the NavigationDrawer in the android support library. This tutorial shows you how to use it.



Test before
If you wish to test before, you can install the application with the following link. The whole source code of the project is also available on github.

logo-app
Your app idea
Michenux
Free   
pulsante-google-play-store
pulsante-appbrain
qrcode-app

Main layout

This is the layout of the activity (file res/layout/main.xml). Notice the root object is a DrawerLayout. You will use the first child (FrameLayout) to display your app contents. The second child is the sliding menu and is a ListView.

<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="@color/purple_dark"
       android:choiceMode="singleChoice"
       android:divider="@android:color/darker_gray"
       android:dividerHeight="0.1dp"
       android:listSelector="@drawable/navdrawer_listselector"/>

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

Describe the menu

The ListView will contains two kinds of objects : sections and section items. Here’s the classes to describe your menu.

NavDrawerItem is the common interface for element types of the menu. The method isEnabled() tells if the item is touchable or not (a section is not).
The method updateActionBarTitle() indicates if the title of the action bar must be updated when the user selects a menu item.

public interface NavDrawerItem {
    public int getId();
    public String getLabel();
    public int getType();
    public boolean isEnabled();
    public boolean updateActionBarTitle();
}

The class to describe a section of the menu :

public class NavMenuSection implements NavDrawerItem {

    public static final int SECTION_TYPE = 0;
    private int id;
    private String label;

    private NavMenuSection() {
    }
   
    public static NavMenuSection create( int id, String label ) {
        NavMenuSection section = new NavMenuSection();
        section.setLabel(label);
        return section;
    }
   
    @Override
    public int getType() {
        return SECTION_TYPE;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    @Override
    public boolean isEnabled() {
        return false;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public boolean updateActionBarTitle() {
        return false;
    }
}

The class to describe a section item of the menu :

public class NavMenuItem implements NavDrawerItem {

    public static final int ITEM_TYPE = 1 ;

    private int id ;
    private String label ; 
    private int icon ;
    private boolean updateActionBarTitle ;

    private NavMenuItem() {
    }

    public static NavMenuItem create( int id, String label, String icon, boolean updateActionBarTitle, Context context ) {
        NavMenuItem item = new NavMenuItem();
        item.setId(id);
        item.setLabel(label);
        item.setIcon(context.getResources().getIdentifier( icon, "drawable", context.getPackageName()));
        item.setUpdateActionBarTitle(updateActionBarTitle);
        return item;
    }
   
    @Override
    public int getType() {
        return ITEM_TYPE;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public int getIcon() {
        return icon;
    }

    public void setIcon(int icon) {
        this.icon = icon;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    @Override
    public boolean updateActionBarTitle() {
        return this.updateActionBarTitle;
    }

    public void setUpdateActionBarTitle(boolean updateActionBarTitle) {
        this.updateActionBarTitle = updateActionBarTitle;
    }
}

Layouts for sections and items

Here’s the layout for sections (file res/layout/navdrawer_section.xml). In this tutorial, a section holds only a title.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:background="@color/purple_dark">
   
    <TextView
       android:id="@+id/navmenusection_label"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:text="Section"
       android:textSize="18sp"
       android:paddingTop="7dp"
       android:paddingBottom="7dp"
       android:textColor="#FFFFFF"
       style="?android:attr/listSeparatorTextViewStyle"
       android:background="@color/purple_dark"/>

</RelativeLayout>

Here’s the layout for menu items (file res/layout/navdrawer_item.xml). In this tutorial, a menu item holds a icon and a title.

<?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="wrap_content"
   android:background="?android:attr/activatedBackgroundIndicator"
   android:textAppearance="?android:attr/textAppearanceListItemSmall"
   android:gravity="center_vertical"
   android:paddingRight="10dp"
   android:minHeight="?android:attr/listPreferredItemHeightSmall"
   >

    <ImageView
       android:id="@+id/navmenuitem_icon"
       android:layout_width="wrap_content"
       android:layout_height="30dp"
        android:layout_centerVertical="true"
        android:paddingLeft="15dp"/>

    <TextView
       android:id="@+id/navmenuitem_label"
       android:layout_width="match_parent"
       android:layout_height="50dp"
       android:layout_toRightOf="@id/navmenuitem_icon"
       android:gravity="center_vertical"
       android:text="TextView"
       android:textColor="#FFFFFF"/>

</RelativeLayout>

Adapter for the list

Below, the adapter to use with the ListView of the menu. It can handle both NavMenuSection and NavMenuItem classes.

public class NavDrawerAdapter extends ArrayAdapter<NavDrawerItem> {

    private LayoutInflater inflater;
   
    public NavDrawerAdapter(Context context, int textViewResourceId, NavDrawerItem[] objects ) {
        super(context, textViewResourceId, objects);
        this.inflater = LayoutInflater.from(context);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = null ;
        NavDrawerItem menuItem = this.getItem(position);
        if ( menuItem.getType() == NavMenuItem.ITEM_TYPE ) {
            view = getItemView(convertView, parent, menuItem );
        }
        else {
            view = getSectionView(convertView, parent, menuItem);
        }
        return view ;
    }
   
    public View getItemView( View convertView, ViewGroup parentView, NavDrawerItem navDrawerItem ) {
       
        NavMenuItem menuItem = (NavMenuItem) navDrawerItem ;
        NavMenuItemHolder navMenuItemHolder = null;
       
        if (convertView == null) {
            convertView = inflater.inflate( R.layout.navdrawer_item, parentView, false);
            TextView labelView = (TextView) convertView
                    .findViewById( R.id.navmenuitem_label );
            ImageView iconView = (ImageView) convertView
                    .findViewById( R.id.navmenuitem_icon );

            navMenuItemHolder = new NavMenuItemHolder();
            navMenuItemHolder.labelView = labelView ;
            navMenuItemHolder.iconView = iconView ;

            convertView.setTag(navMenuItemHolder);
        }

        if ( navMenuItemHolder == null ) {
            navMenuItemHolder = (NavMenuItemHolder) convertView.getTag();
        }
                   
        navMenuItemHolder.labelView.setText(menuItem.getLabel());
        navMenuItemHolder.iconView.setImageResource(menuItem.getIcon());
       
        return convertView ;
    }

    public View getSectionView(View convertView, ViewGroup parentView,
            NavDrawerItem navDrawerItem) {
       
        NavMenuSection menuSection = (NavMenuSection) navDrawerItem ;
        NavMenuSectionHolder navMenuItemHolder = null;
       
        if (convertView == null) {
            convertView = inflater.inflate( R.layout.navdrawer_section, parentView, false);
            TextView labelView = (TextView) convertView
                    .findViewById( R.id.navmenusection_label );

            navMenuItemHolder = new NavMenuSectionHolder();
            navMenuItemHolder.labelView = labelView ;
            convertView.setTag(navMenuItemHolder);
        }

        if ( navMenuItemHolder == null ) {
            navMenuItemHolder = (NavMenuSectionHolder) convertView.getTag();
        }
                   
        navMenuItemHolder.labelView.setText(menuSection.getLabel());
       
        return convertView ;
    }
   
    @Override
    public int getViewTypeCount() {
        return 2;
    }
   
    @Override
    public int getItemViewType(int position) {
        return this.getItem(position).getType();
    }
   
    @Override
    public boolean isEnabled(int position) {
        return getItem(position).isEnabled();
    }
   
   
    private static class NavMenuItemHolder {
        private TextView labelView;
        private ImageView iconView;
    }
   
    private class NavMenuSectionHolder {
        private TextView labelView;
    }
}

AbstractNavDrawerActivity

There’s a lot of code to write in the activity to manage the Navigation Drawer. I have written a class to simplify the stuff. Just inherit your activity from this one. If you want more information how it works behind, i suggest you to read the android tutorial : http://developer.android.com/training/implementing-navigation/nav-drawer.html, most of the code below comes from this tutorial.

public abstract class AbstractNavDrawerActivity extends FragmentActivity {

    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
   
    private ListView mDrawerList;
   
    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
   
    private NavDrawerActivityConfiguration navConf ;
   
    protected abstract NavDrawerActivityConfiguration getNavDrawerConfiguration();
   
    protected abstract void onNavItemSelected( int id );
   
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
        navConf = getNavDrawerConfiguration();
       
        setContentView(navConf.getMainLayout());
       
        mTitle = mDrawerTitle = getTitle();
       
        mDrawerLayout = (DrawerLayout) findViewById(navConf.getDrawerLayoutId());
        mDrawerList = (ListView) findViewById(navConf.getLeftDrawerId());
        mDrawerList.setAdapter(navConf.getBaseAdapter());
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
       
        this.initDrawerShadow();
       
        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);
       
        mDrawerToggle = new ActionBarDrawerToggle(
                this,
                mDrawerLayout,
                getDrawerIcon(),
                navConf.getDrawerOpenDesc(),
                navConf.getDrawerCloseDesc()
                ) {
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu();
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);
    }
   
    protected void initDrawerShadow() {
        mDrawerLayout.setDrawerShadow(navConf.getDrawerShadow(), GravityCompat.START);
    }
   
    protected int getDrawerIcon() {
        return R.drawable.ic_drawer;
    }
   
    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }
   
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if ( navConf.getActionMenuItemsToHideWhenDrawerOpen() != null ) {
            boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
            for( int iItem : navConf.getActionMenuItemsToHideWhenDrawerOpen()) {
                menu.findItem(iItem).setVisible(!drawerOpen);
            }
        }
        return super.onPrepareOptionsMenu(menu);
    }
   
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        else {
            return false;
        }
    }
   
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ( keyCode == KeyEvent.KEYCODE_MENU ) {
            if ( this.mDrawerLayout.isDrawerOpen(this.mDrawerList)) {
                this.mDrawerLayout.closeDrawer(this.mDrawerList);
            }
            else {
                this.mDrawerLayout.openDrawer(this.mDrawerList);
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
   
    protected DrawerLayout getDrawerLayout() {
        return mDrawerLayout;
    }

    protected ActionBarDrawerToggle getDrawerToggle() {
        return mDrawerToggle;
    }
   
    private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position);
        }
    }
   
    public void selectItem(int position) {
        NavDrawerItem selectedItem = navConf.getNavItems()[position];
       
        this.onNavItemSelected(selectedItem.getId());
        mDrawerList.setItemChecked(position, true);
       
        if ( selectedItem.updateActionBarTitle()) {
            setTitle(selectedItem.getLabel());
        }
       
        if ( this.mDrawerLayout.isDrawerOpen(this.mDrawerList)) {
            mDrawerLayout.closeDrawer(mDrawerList);
        }
    }
   
    @Override
    public void setTitle(CharSequence title) {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }
}

NavDrawerActivityConfiguration

NavDrawerActivityConfiguration is the bean to configure the sliding menu and is needed by the AbstractNavDrawerActivity activity.

Here’s a short description of the properties :

public class NavDrawerActivityConfiguration {

    private int mainLayout;
    private int drawerShadow;
    private int drawerLayoutId;
    private int leftDrawerId;
    private int[] actionMenuItemsToHideWhenDrawerOpen;
    private NavDrawerItem[] navItems;
    private int drawerOpenDesc;
    private int drawerCloseDesc;
    private BaseAdapter baseAdapter;

    public int getMainLayout() {
        return mainLayout;
    }

    public void setMainLayout(int mainLayout) {
        this.mainLayout = mainLayout;
    }

    public int getDrawerShadow() {
        return drawerShadow;
    }

    public void setDrawerShadow(int drawerShadow) {
        this.drawerShadow = drawerShadow;
    }

    public int getDrawerLayoutId() {
        return drawerLayoutId;
    }

    public void setDrawerLayoutId(int drawerLayoutId) {
        this.drawerLayoutId = drawerLayoutId;
    }

    public int getLeftDrawerId() {
        return leftDrawerId;
    }

    public void setLeftDrawerId(int leftDrawerId) {
        this.leftDrawerId = leftDrawerId;
    }

    public int[] getActionMenuItemsToHideWhenDrawerOpen() {
        return actionMenuItemsToHideWhenDrawerOpen;
    }

    public void setActionMenuItemsToHideWhenDrawerOpen(
            int[] actionMenuItemsToHideWhenDrawerOpen) {
        this.actionMenuItemsToHideWhenDrawerOpen = actionMenuItemsToHideWhenDrawerOpen;
    }

    public NavDrawerItem[] getNavItems() {
        return navItems;
    }

    public void setNavItems(NavDrawerItem[] navItems) {
        this.navItems = navItems;
    }

    public int getDrawerOpenDesc() {
        return drawerOpenDesc;
    }

    public void setDrawerOpenDesc(int drawerOpenDesc) {
        this.drawerOpenDesc = drawerOpenDesc;
    }

    public int getDrawerCloseDesc() {
        return drawerCloseDesc;
    }

    public void setDrawerCloseDesc(int drawerCloseDesc) {
        this.drawerCloseDesc = drawerCloseDesc;
    }

    public BaseAdapter getBaseAdapter() {
        return baseAdapter;
    }

    public void setBaseAdapter(BaseAdapter baseAdapter) {
        this.baseAdapter = baseAdapter;
    }
}

Example of activity

This is an example of a subclass that inherits from AbstractNavDrawerActivity. Look at how the menu is described to make your own and
look at the method onNavItemSelected() to handle clicks on menu items.

public class YourAppMainActivity extends AbstractNavDrawerActivity {
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if ( savedInstanceState == null ) {
            getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new MainFragment()).commit();
        }
    }
   
    @Override
    protected NavDrawerActivityConfiguration getNavDrawerConfiguration() {
       
        NavDrawerItem[] menu = new NavDrawerItem[] {
                NavMenuSection.create( 100, "Demos"),
                NavMenuItem.create(101,"List/Detail (Fragment)", "navdrawer_friends", false, this),
                NavMenuItem.create(102, "Airport (AsyncTask)", "navdrawer_airport", true, this),
                NavMenuSection.create(200, "General"),
                NavMenuItem.create(202, "Rate this app", "navdrawer_rating", false, this),
                NavMenuItem.create(203, "Eula", "navdrawer_eula", false, this),
                NavMenuItem.create(204, "Quit", "navdrawer_quit", false, this)};
       
        NavDrawerActivityConfiguration navDrawerActivityConfiguration = new NavDrawerActivityConfiguration();
        navDrawerActivityConfiguration.setMainLayout(R.layout.main);
        navDrawerActivityConfiguration.setDrawerLayoutId(R.id.drawer_layout);
        navDrawerActivityConfiguration.setLeftDrawerId(R.id.left_drawer);
        navDrawerActivityConfiguration.setNavItems(menu);
        navDrawerActivityConfiguration.setDrawerShadow(R.drawable.drawer_shadow);      
        navDrawerActivityConfiguration.setDrawerOpenDesc(R.string.drawer_open);
        navDrawerActivityConfiguration.setDrawerCloseDesc(R.string.drawer_close);
        navDrawerActivityConfiguration.setBaseAdapter(
            new NavDrawerAdapter(this, R.layout.navdrawer_item, menu ));
        return navDrawerActivityConfiguration;
    }
   
    @Override
    protected void onNavItemSelected(int id) {
        switch ((int)id) {
        case 101:
            getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new FriendMainFragment()).commit();
            break;
        case 102:
            getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new AirportFragment()).commit();
            break;
        }
    }
}

Drawables and resources

This drawable (res/drawable/listitem_background.xml) is used to configure the background color of the selected item.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true" android:drawable="@color/purple_middle" />
    <item android:drawable="@android:color/transparent" />
</selector>

This one is used to configure the background color when a menu item is pressed navdrawer_listselector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
  android:exitFadeDuration="@android:integer/config_mediumAnimTime">

   <item android:drawable="@color/purple_light" android:state_pressed="true"/>
   <item android:drawable="@color/purple_light" android:state_selected="true"/>
   <item android:drawable="@color/purple_light" android:state_activated="true"/>

</selector>

In your application theme, add the following property :

<item name="android:activatedBackgroundIndicator">@drawable/listitem_background</item>

My color file (res/values/color.xml):

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">      
    <color name="purple_light">#a276eb</color>
    <color name="purple_middle">#8658ce</color>
    <color name="purple_dark">#6a3ab2</color>
</resources>

Add the following strings in your string file (res/values/strings.xml)

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

Get the missing drawables with the following links :

Finally
I hope you find this tutorial useful. Don’t hesitate to communicate your customizations/optimizations so i can improve this tutorial.

Share Button

Comments

44 Responses to “Android : Navigation Drawer”

  1. Flo on August 1st, 2013 11:21 am

    Is it allowed to me to use your code in my projects without any limitations ? ;)

    The Tutorial is so good , there must be a snag :D

  2. Michenux on August 1st, 2013 12:57 pm

    Yes, you can use it without any limitations. If you have time, don’t hesitate to rate my app on the play store. Good luck with your projects.

  3. Wendell on August 8th, 2013 6:57 pm

    Hi! this is a nicely done navigation, I download the source code on github and import it on Eclipse ADT but I’m getting a lot of error. Could you please help me how to make it work.. Thanks!

  4. Michenux on August 9th, 2013 8:22 am

    Use Android Studio, not Eclipse ADT.

  5. siddhu on August 13th, 2013 7:23 pm

    can you please provide download link

  6. Michenux on August 13th, 2013 9:20 pm

    Siddhu : it is available on github

  7. Shikha on August 20th, 2013 4:42 pm

    Hi
    This is really a great tutorial . Could you please release a version for eclipse. Its really hard to import this code over Eclipse..I would really appreciate that. Thanks

    PS: I am really desperate to get this working please help!!

  8. smaybe on August 21st, 2013 8:14 pm

    thanks so much for this !

  9. kains on August 23rd, 2013 11:14 am

    Hi
    Nice tutorial but can you please let me know how to use it with simplecursoradapter

  10. KzD on August 26th, 2013 12:36 am

    Looks awesome. I will test this tonight. Unfortunately, Google’s example doesn’t allow the use of icons and headings like yours does. If this works, I’m happy to drop a donation to your cause.

  11. Thor H. on August 26th, 2013 12:41 pm

    I’ve gone crazy so hard then finally found this tutorial! It’s the best online! Thank you so much!

  12. Michael on September 10th, 2013 11:50 am

    I really liked the design ! Clean and clever.

  13. Shyam on September 13th, 2013 11:24 pm

    Excellent tutorial. Thanks :)

  14. Thanos on September 21st, 2013 4:12 am

    Really good tutorial thanks. Now I am wondering how can I place menus at the bottom of the layout? like foursquare on android does here with “Find Friends” and “Settings menus?
    http://i.stack.imgur.com/UlHAs.png

  15. Vineet Ashtekar on September 21st, 2013 4:41 am

    this is an awesome tutorials..! but can yu plz make a version for eclipse.. I’m badly in need of this navigation drawer. .. Plz make it asap.. thanks in advance

  16. Adamsy on October 3rd, 2013 5:48 am

    Michenaud, this an awesome post. However, is it possible to tweak the code to allow the hardware menu button to display the default menu and the nav drawer only to be controlled by the application icon on the left of the action bar or when the user swipes from the left to the right as described here: http://developer.android.com/design/patterns/navigation-drawer.html

    Your implementation here is overriding the default menu button action, I can’t seem to figure out why that is so.

    Thanks.

  17. Michenux on October 3rd, 2013 8:31 pm

    Adamsy: just remove the method onKeyDown in the class AbstractNavDrawerActivity.

  18. Thinh Ng on October 8th, 2013 10:07 am

    Thanks very much! Nice code!

  19. Rayman on October 29th, 2013 9:31 am

    Great tutorial!!!
    Someone please teach me how to hide actionbar icon/menu when drawer is open, thanks!

  20. dev on November 8th, 2013 8:35 pm

    can i use this for 2.3+? cos navigation drawer example given by google doest work fr 2.3

  21. foo on November 12th, 2013 1:13 pm

    Hi,

    Thanks for this tutorial. Much appreciated. I need the data for the menu items to come from a json file. Can you help me with that? http://stackoverflow.com/questions/19914334/navigation-drawer-menu-item-array

  22. Michenux on November 16th, 2013 2:28 pm

    I can just give you the main steps :
    - I would make the json call using volley library from google.
    - On response, i would update the data in the adapter of the listView. Because the navdrawer contains a standard listview and an adapter.
    - Then, i would call adapter.notifyDatasetChanged() to notify the adapter that the data have changed.

  23. Michenux on November 16th, 2013 2:32 pm

    Yes, you can. Look at https://github.com/Michenux/YourAppIdea. It is quite the same code for navigation drawer as in the tutorial except some minor modifications so it can work on Android 2.3+

  24. Adam on November 29th, 2013 6:21 pm

    Nice tutorial. There is one concept that I still can’t seem to get around with the new NavigationDrawer as well the custom sliding menu implementations. I’d like to include the nav component to link directly to most screens in my app in addition to have screens accessed from other controls in the app ( i.e. a button on a screen that brings you to another screen).
    The question that I have is, does the introduction of this type of nav control force one to design their apps with a single landing activity that manages all full screen content with fragments?

  25. Michenux on November 29th, 2013 9:18 pm

    Hi Adam, nice question. My point of view : when you use the navigation drawer, you have to manage all with fragments inside a single activity.

  26. Jason on November 30th, 2013 11:52 am

    Thank you for sharing this! That is a very elegant way of handling variable-length menus instead of using index-based cases for a list view. With always swapping fragments, don’t you lose the use of the Back button to move from a detail back up to a list?

  27. gtrec on December 6th, 2013 11:24 am

    Hi,

    Thanks for this nice tutorial; it helped me a lot since I’m new to Android development.

    Only one thing: how do you set up the horizontal purple line, under the main title?

    Thanks so much,
    Gaia

  28. Sandeep on December 12th, 2013 9:57 am

    Thanks a ton mate.

  29. Dhamen on December 14th, 2013 11:53 pm

    Nice Tutorial mate. My question how can I support RTL languages, actually when you change the mobile language to Arabic or Hebrew the navigation items disappear. probably because they are left aliened. Thank you.

  30. omid8bimo on December 15th, 2013 1:42 pm

    Thanks for the article. I have a question though, if i want to extends my activity from that base activity but have my activity’s own xml, is it possible? because when i use setContentView on the extended activity, the navDrawer no longer shows up.

  31. Michenux on December 15th, 2013 9:25 pm

    About the horizontal purple line, i used this website to create the action bar style :
    http://jgilfelt.github.io/android-actionbarstylegenerator/

  32. Michenux on December 15th, 2013 9:33 pm

    I don’t know so much about RTL languages. I have seen about the attribute : android:textDirection=”anyRtl”
    and i have seen that RTL support has been improved from Android 4.2 :
    http://android-developers.blogspot.fr/2013/03/native-rtl-support-in-android-42.html

    Finally, about RTL and navigation drawer, you can see the following in the documentation (http://developer.android.com/training/implementing-navigation/nav-drawer.html) :
    The drawer view (the ListView) must specify its horizontal gravity with the android:layout_gravityattribute. To support right-to-left (RTL) languages, specify the value with “start” instead of “left” (so the drawer appears on the right when the layout is RTL).

  33. Michenux on December 15th, 2013 9:37 pm

    Don’t use setContentView but :
    Create a fragment that uses your layout then show the fragment using the following code :

    activity.getSupportFragmentManager().beginTransaction()
    .replace(R.id.content_frame, new MainFragment(), HOME_FRAGMENT_TAG).commit();
  34. Fahim on December 17th, 2013 6:08 am

    Hi,

    I have one basic question. I have 5 different Activity , each activity is independent of others, and each activity has it’s own layout file.

    Now, do you advise to use Navigation Drawer for my App Menu? If so, do I need to merge those 5 activities into one, and use 5 fragments to load 5 different layouts? It will be a very hard and tiring for me though.

    Thanks,

  35. Michenux on December 20th, 2013 10:17 pm

    It’s a great question. The best is to migrate your 5 activities into fragments and have only one activity. If you want to keep your activities, i would have one advice : disable the animation when you start your activities : it will be more fluid. Application gmail does that : one main activity, and another one for the mail content, and there’s no animation on the transition.

  36. besut on January 21st, 2014 11:41 am

    Hi,
    First of all, great tutorial.

    I am very new in Android/Java and want to ask the best method to conserve/savedInstanceState of the fragment views (seekbar,editext etc) as we navigate via the drawer.

    I am trying to reproduce effect of single activity instance when we switch the activities around (i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)), i.e. to reuse the same fragment.

    Thank you in advance for your clarification. I have tried reading the documentation/tried playing with minor savedInstanceState in the fragment but I still couldn’t make it work

  37. besut on January 23rd, 2014 1:34 pm

    Managed to find the solution for my question, used view pager for fragment to managed all the transition and state,

    Thank you for the great tutorial

  38. Sersast on February 4th, 2014 11:25 pm

    Very nice tutorial. However, I got stuck while trying to make the action items show up for each fragment. They simply not appear.

    How can I make them appear?

    Thanks in advance!

  39. Vadim on February 7th, 2014 10:06 am

    This is really great tutorial! One of the very few, that works right after copy-paste.
    Just small complement from me:
    I’ve going to suuport API 8 in my app, so I’ve imported support.v7 library and extend ActionBarActivity(instead of FragmentActivity) in AbstractNavDrawerActivity. Also call getSupportActionBar(instead of getActionBar).
    Few more tiny changes and awesome drawer appears on Android 2.2 and abowe:)
    Thanks again, and good luck.

  40. Maxrunner on February 10th, 2014 7:15 pm

    How about this example for extending the abstract navdraw class:

    http://stackoverflow.com/a/4922740/382115

  41. Stephan on February 20th, 2014 5:20 pm

    Super tutorial.
    I have a question. How can I trigger a function like
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

    in a Fragment. In the MainActivity startActivityForResult(getIntent(), eRequest.Save ); i trigger these function.

  42. off van Hooijdonk on February 23rd, 2014 11:39 am

    Hi.
    A really nice example! I’ve got two questions:
    1 – Why making abstract activity class if we use a single activity with drawer and all other layouts are navigated as fragments? Why not just make a host activity implementing everything? Maybe it’s a matter of code reusing?
    2 – I tried navif=gating with Drawer and fragments – and I got realy messed up with events handling in fragments – it is really a disaster! I got several TextViews and a ListView in fragment – and I can’t handle clicking on a ListView item – doesn’t work at all. I googled and tried a lot – fail. While clicking on an image inside a ListView item works. Maybe you could helpme? Many Thanks

  43. Gilang Pradana on March 1st, 2014 1:37 pm

    Thanks for this tutorial, it’s work great to my app… but i have a simple question, how to toggle the navigation drawer via the action bar title???

  44. Waki on July 4th, 2014 7:45 am

    Great tutorial! Thank you, it’s really help me.

Leave a Reply