StackTips

Navigation Drawer Android Example

nilan avtar

Written by

Nilanchala,  16 min read,  2.9K views, updated on Sept. 17, 2023

1. Introduction

Android navigation drawer is a one of the most common used design pattern that displays the app’s main navigation links on the left side of the screen. It is not visible by default, and shown when swiped from left to right or by clicking the navigation menu icon from ActionBar.

The following example explains, how to implement a navigation drawer using  Android Support Library DrawerLayout API.

2. When to Use Navigation Drawer

Navigation drawer is an overlay panel, that is replaced with the legacy application dashboard screen or menu. Now we don’t need to create a dedicated activity for showing all application options. You can simply it further by just using navigation drawer.

Before you decide to use a navigation drawer in your app, you should understand the use cases and design principles defined in the Navigation Drawer design guide. It is not an general replacement for top-level menu navigation.

Follow official Android on design guidelines follow for more information.

3. Navigation Drawer Example

The following section of this tutorial, describes step by step approach to Implement a navigation drawer using the DrawerLayout APIs available in the Android Support Library. Some of the steps includes

  • Create drawer layout
  • Initialize navigation drawer layout
  • Handle navigation drawer click
  • Update content based on selection

Navigation Drawer Android Example

4. Creating a Drawer Layout

For creating a navigation drawer, first we need to declare the drawer layout in your main activity  where you want to show the navigation drawer. Add android.support.v4.widget.DrawerLayout as root view of activity layout.

A DrawerLayout can have the layout for list to be shown inside navigation drawer and layout for main content view. In this example, the DrawerLayout contains two child views; one FrameLayout for main content, and a ListView for the navigation drawer. The FrameLayout is used to hold the child view’s populated by a Fragment at runtime.

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

    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- The navigation drawer list-->
    <ListView
        android:id="@+id/drawer_list"
        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>

Key Notes:

  • The main content view is used as first child in the DrawerLayout. The XML order implies z-ordering and the drawer must be on top of the content.
  • The main content view is set to match the parent view’s width and height, because it represents the entire UI when the navigation drawer is hidden.
  • The width of drawer view is specified in dp (density independent pixels) units and the height matches the parent view. The drawer width should be no more than 320dp so the user can always see a portion of the main content.

5. Initialize the Drawer List

Now, first initialize the navigation drawer’s list of items. As here the navigation drawer consists a ListView, so the list can be populated by an Adapter.

items = getResources().getStringArray(R.array.menus);

/* Getting reference to the DrawerLayout */
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.drawer_list);

/* Creating an ArrayAdapter to add items to mDrawerList */
ArrayAdapter adapter = new ArrayAdapter(this,
        R.layout.drawer_list_item, items);

/* Setting the adapter to mDrawerList */
mDrawerList.setAdapter(adapter);

6. Handle Navigation Click Events

When the user selects an item in the drawer’s list, the system calls onItemClick() on the OnItemClickListener given to setOnItemClickListener(). In this example, selecting each item in the list inserts a different Fragment into the main content view FrameLayout.

// Setting item click listener to mDrawerList
mDrawerList.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        selectedPosition = position;
        //Replace fragment content
        updateFragment();
        mDrawerLayout.closeDrawer(mDrawerList);
     }
});

Notice that in the above example we are using updateFragment() method that takes responsibility to update the content based on navigation drawer menu click. For the sake of simplicity, example loads the same WebView  with different url. Add the following method to your activity.

public void updateFragment() {
    FragmentManager fragmentManager = getFragmentManager();
    WebViewFragment rFragment = new WebViewFragment();

    // Passing selected item information to fragment
    Bundle data = new Bundle();
    data.putString("title", items[selectedPosition]);
    data.putString("url", getUrl());
    rFragment.setArguments(data);

    //Replace fragment
    FragmentTransaction ft = fragmentManager.beginTransaction();
    ft.replace(R.id.content_frame, rFragment);
    ft.commit();
}

7. Handle Drawer Open and Close Events

We can also listen to the drawer open and close event. To listen for drawer open and close events, we can extend the ActionBarDrawerToggle class. The ActionBarDrawerToggle implements DrawerLayout.DrawerListener.

/* Getting reference to the ActionBarDrawerToggle */
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
    /* Called when drawer is closed */
    public void onDrawerClosed(View view) {
         //Put your code here
    }

  /* Called when a drawer is opened */
  public void onDrawerOpened(View drawerView) {
     //Put your code here
  }
};
/* Setting DrawerToggle on DrawerLayout */
mDrawerLayout.setDrawerListener(mDrawerToggle);

8. Download Complete Source

Download Source Code on Github

MainActivity.java

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;
    private String mTitle = "Navigation Drawer";
    private String[] items;
    private int selectedPosition;

    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getActionBar().setTitle(mTitle);

        items = getResources().getStringArray(R.array.menus);
        // Getting reference to the DrawerLayout 
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.drawer_list);

        /* Creating an ArrayAdapter to add items to mDrawerList */
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.drawer_list_item, items);
        mDrawerList.setAdapter(adapter);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {

            /* Called when drawer is closed */
            public void onDrawerClosed(View view) {
                //Put your code here
            }

            /* Called when a drawer is opened */
            public void onDrawerOpened(View drawerView) {
                //Put your code here
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        // Enabling Home button
        getActionBar().setHomeButtonEnabled(true);
        getActionBar().setDisplayHomeAsUpEnabled(true);

        // Setting item click listener for the listview mDrawerList
        mDrawerList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                selectedPosition = position;

                /* Replace fragment content */
                updateFragment();

               /* Closing the drawer */
                mDrawerLayout.closeDrawer(mDrawerList);
            }
        });

        /* Setting default fragment */
        selectedPosition = 0;
        updateFragment();
    }

    public void updateFragment() {
        /* Getting reference to the FragmentManager */
        FragmentManager fragmentManager = getFragmentManager();

        /* Creating fragment instance */
        WebViewFragment rFragment = new WebViewFragment();

        /* Passing selected item information to fragment */
        Bundle data = new Bundle();
        data.putString("title", items[selectedPosition]);
        data.putString("url", getUrl());
        rFragment.setArguments(data);

        /* Replace fragment */
        FragmentTransaction ft = fragmentManager.beginTransaction();
        ft.replace(R.id.content_frame, rFragment);
        ft.commit();
    }

    protected String getUrl() {
        StringBuffer url = new StringBuffer("http://stacktips.com");
        if (selectedPosition > 0) {
            url.append("/topics/" + items[selectedPosition].toLowerCase());
        }
        return url.toString();
    }

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