Android Sliding Menu using Navigation Drawer

7 min read

A - Introduction Android Sliding Menu

Nowadays, a lot of Android applications use Sliding Menu to navigate between app's modules/ screens. The Sliding Menu is hidden in the normal state and can be shown by swiping horizontally gesture or tapping on the app icon on the Action Bar. Android Sliding Menu

Previously, if you want to create a Sliding Menu like this, the only way is using a third party library.

But now, Google support it with a newer concept called Navigation Drawer.

According to Google:

The navigation drawer is a panel that transitions in from the left edge of the screen and displays the app’s main navigation options.
In this post, we will learn how to create a Android Sliding Menu using Navigation Drawer.

B - Demo Application

1. Prepare resources

First of all, you need to download some images for the Sliding Menu and add them to the drawable folder:
  • Sliding menu icon: ic_drawer
  • Home icon: home
  • Settings icon: settings
  • Notifications icon: notifications
  • About icon: about
Open string.xml file, add some string variables for Sliding Menu items and icons name: {% highlight java %}
<string name="app_name">Demo Sliding Menu</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>

<!-- Sliding Menu items -->
<string-array name="nav_drawer_items">
    <item >Home</item>
    <item >Notifications</item>
    <item >Settings</item>
    <item >About</item>
</string-array>

<!-- Sliding Menu item icons -->
<array name="nav_drawer_icons">
    <item>@drawable/home</item>
    <item>@drawable/notifications</item>
    <item>@drawable/settings</item>
    <item>@drawable/about</item>
</array>
{% endhighlight %}  

2. Edit main layout

Open activity_main.xml file and type the following code:

{% highlight java %} <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 to display Fragments -->
<FrameLayout
    android:id="@+id/fragment_detail"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<!-- Listview to display Sliding Menu -->
<ListView
    android:id="@+id/lv_sliding_menu"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="#000"
    android:dividerHeight="1dp"/>
    

</android.support.v4.widget.DrawerLayout> {% endhighlight %}  

The FrameLayout will hold the appropriate Fragment (default is Home fragment).

The ListView will role the Sliding Menu.

3. Create Adapter for Sliding Menu ListView

As I mentioned in the Custom ListView post, every Custom ListView need an Adapter. But before coding for the Adapter, We need to create some layouts for the Sliding Menu ListView.

Create a layout file under the res —> layouts folder and name it lv_item_sliding_menu.xml. This layout has a ImageView and TextView to display Sliding Menu item. {% highlight java %}

<ImageView
    android:id="@+id/img_sliding_menu_item"
    android:layout_width="32dp"
    android:layout_height="32dp"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:src="@drawable/home" />

<TextView
    android:id="@+id/tv_sliding_menu_item"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/img_sliding_menu_item"
    android:layout_toRightOf="@+id/img_sliding_menu_item"
    android:text="Home"
    android:layout_marginLeft="10dp"
    android:textAppearance="?android:attr/textAppearanceMedium" />
{% endhighlight %}  

To bind items to a ListView. We need an entity to describe that item.

Create SlidingMenuItem class with following properties: {% highlight java %} public class SlidingMenuItem { String title; int icon;

public SlidingMenuItem(String title, int icon) {
    this.title = title;
    this.icon = icon;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public int getIcon() {
    return icon;
}

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

} {% endhighlight %}  

Now, everything is ready to code the adapter.

Create SlidingMenuAdapter class that extends BaseAdapter: {% highlight java %} public class SlidingMenuAdapter extends BaseAdapter {

private Context context;
private ArrayList<SlidingMenuItem> items;

public SlidingMenuAdapter(Context context, ArrayList<SlidingMenuItem> items) {
    this.context = context;
    this.items = items;
}

@Override
public int getCount() {
    return items.size();
}

@Override
public Object getItem(int index) {
    return items.get(index);
}

@Override
public long getItemId(int index) {
    return index;
}

@Override
public View getView(int index, View view, ViewGroup arg2) {
    if (view == null) {
        LayoutInflater mInflater = (LayoutInflater)
        context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        view = mInflater.inflate(R.layout.lv_item_sliding_menu, null);
    }

    ImageView imgIcon = (ImageView) view.findViewById(R.id.img_sliding_menu_item);
    TextView txtTitle = (TextView) view.findViewById(R.id.tv_sliding_menu_item);

    SlidingMenuItem item = items.get(index);

    imgIcon.setImageResource(item.getIcon());
    txtTitle.setText(item.getTitle());

    return view;
}

} {% endhighlight %}  

Until now, we did every thing needed for the Sliding Menu ListView (the layout, the entity and the adapter).

Now, it’s time to implement it in the MainActivity with the following major steps:

  • Creating fragments for each Sliding Menu item
  • Create an instance of SlidingMenuAdapter and adding initial data
  • Assigning the adapter to Sliding Menu ListView
  • Handling on item click event to show the appropriate fragment for the clicked item

4. Create Fragments for each Sliding Menu items

Here, I only show to you the layout xml file and the code file of Home fragment. The others are similar and can be found in source code. Each fragment contains a TextView to describe the current screen. fragment_home.xml {% highlight java %}

<TextView
    android:id="@+id/tv_home"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:text="Home"
    android:textAppearance="?android:attr/textAppearanceLarge" />
{% endhighlight %}  

HomeFragment.java {% highlight java %}public class HomeFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_home, container, false); return rootView; } } {% endhighlight %}  

5. MainActivity

Open MainActivity.java and implement the remaining major steps. The following code is the completed code for MainActivity. I noted so many comments there so you guys can understand it easily: {% highlight java %}public class MainActivity extends Activity { private DrawerLayout drawerLayout; private ListView lvSlidingMenu; private ActionBarDrawerToggle drawerToggle; // Navigation Drawer titles private CharSequence drawerTitle; private CharSequence appTitle;
// Sliding Menu items 
private String[] titles;
private TypedArray icons;
private ArrayList slidingMenuItems;
private SlidingMenuAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    appTitle = drawerTitle = getTitle();

    // Load resources 
    titles = getResources().getStringArray(R.array.nav_drawer_items);
    icons = getResources().obtainTypedArray(R.array.nav_drawer_icons);

    // Get Sliding Menu ListView istance 
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    lvSlidingMenu = (ListView) findViewById(R.id.lv_sliding_menu);
    slidingMenuItems = new ArrayList();

    // Creating and Adding SlidingMenuItems 
    slidingMenuItems.add(new SlidingMenuItem(titles[0], icons.getResourceId(0, -1)));
    slidingMenuItems.add(new SlidingMenuItem(titles[1], icons.getResourceId(1, -1)));
    slidingMenuItems.add(new SlidingMenuItem(titles[2], icons.getResourceId(2, -1)));
    slidingMenuItems.add(new SlidingMenuItem(titles[3], icons.getResourceId(3, -1)));

    // Recycle the typed array 
    icons.recycle();
    lvSlidingMenu.setOnItemClickListener(new SlideMenuClickListener());

    // Assign adapter to listview 
    adapter = new SlidingMenuAdapter(getApplicationContext(), slidingMenuItems);
    lvSlidingMenu.setAdapter(adapter);

    // Enable action bar app icon and behaving it as toggle button 
    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);
    drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.drawable.ic_drawer,
            // Navigation Drawer 
            icon R.string.app_name,
            //Navigation Drawer open - description for accessibility 
            R.string.app_name
            // Navigation Drawer close - description for accessibility 
    ) {
        public void onDrawerClosed(View view) {
            getActionBar().setTitle(appTitle);
            invalidateOptionsMenu();
        }

        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(drawerTitle);
            invalidateOptionsMenu();
        }
    }; drawerLayout.setDrawerListener(drawerToggle);
    if (savedInstanceState == null) {
        // On first time, show Home Fragment
        displayView(0);
    }
}

/**
 * Slide menu item click listener *
 */
private class SlideMenuClickListener implements ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // Display appropriate fragment for selected item 
        displayView(position);
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Toggle Navigation Drawer on selecting action bar app icon/title 
    if (drawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle action bar actions click 
    switch (item.getItemId()) {
        case R.id.action_settings:
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
} /* * * Called when invalidateOptionsMenu() is triggered */

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    // If Navigation Drawer is opened, hide the action items 
    boolean drawerOpen = drawerLayout.isDrawerOpen(lvSlidingMenu);
    menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
    return super.onPrepareOptionsMenu(menu);
}

/**
 * Display fragment view for selected Navigation Drawer list item *
 */
private void displayView(int position) {
    Fragment fragment = null;
    switch (position) {
        case 0:
            fragment = new HomeFragment();
            break;
        case 1:
            fragment = new NotificationsFragment();
            break;
        case 2:
            fragment = new SettingsFragment();
            break;
        case 3:
            fragment = new AboutFragment();
            break;
        default:
            break;
    }
    if (fragment != null) {
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.fragment_detail, fragment).commit();

        // Update selected item and title, then close the drawer 
        lvSlidingMenu.setItemChecked(position, true);
        lvSlidingMenu.setSelection(position);
        setTitle(titles[position]);
        drawerLayout.closeDrawer(lvSlidingMenu);
    } else {
        // Log error
        Log.e("MainActivity", "Error in creating fragment");
    }
}

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

/**
 * When using the ActionBarDrawerToggle, you must call it during * onPostCreate() and onConfigurationChanged()...
 */
@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred. 
    drawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggls 
    drawerToggle.onConfigurationChanged(newConfig);
}

}

{% endhighlight %}  

Run the project and enjoy: Android Sliding Menu

C - Download source code

https://drive.google.com/file/d/0Bw3dwdSezn6faXJYQW5ibG5zWnM/edit?usp=sharing

Iced Tea Labs

A technical blog managed by a geek who loves climbing

GitHub Twitter RSS

© 2026 Trinh Le. All rights reserved.