Tutorial

Android Navigation Drawer Example Tutorial

Published on August 3, 2022
author

Anupam Chugh

Android Navigation Drawer Example Tutorial

In this tutorial we’ll implement a Navigation Drawer in our android application. Android navigation drawer is a sliding menu and it’s an important UI component. You will see navigation drawer in most of the android applications, it’s like navigation menu bars in the websites.

Android Navigation Drawer

Android Navigation Drawer is a sliding left menu that is used to display the important links in the application. Navigation drawer makes it easy to navigate to and fro between those links. It’s not visible by default and it needs to opened either by sliding from left or clicking its icon in the ActionBar. In broader terms, Navigation Drawer is an overlay panel, which is a replacement of an activity screen which was specifically dedicated to show all the options and links in the application. In this android navigation drawer tutorial we’ll implement the navigation drawer using the Drawer Layout API present in Android Support Library. We’ll show 3 fragment views that can be opened from the drawer items.

Android Navigation Drawer Project Structure

android navigation drawer

Android Navigation Drawer Example

To implement the Navigation Drawer we first need to add android.support.v4.widget.DrawerLayout as the root of the activity layout as shown below. activity_main.xml

<android.support.v4.widget.DrawerLayout 
    xmlns:android="https://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

    <LinearLayout
        android:id="@+id/container_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <include
            android:id="@+id/toolbar"
            layout="@layout/toolbar" />
    </LinearLayout>


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

    </LinearLayout>

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

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

The menu options in the navigation drawer are stored in the form of a ListView. Each option opens in the FrameLayout. We’ve used a ToolBar in place of an ActionBar here. ToolBar has been introduced since Android 5.0 as a generalisation of ActionBar. It gives us more control and flexibility to modify and its easier to interleave with other views in the hierarchy. The layout ToolBar is defined in the xml layout given below. toolbar.xml

<android.support.v7.widget.Toolbar xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:local="https://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    local:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    local:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

We need to use the Theme Theme.AppCompat.NoActionBar in the styles.xml when using Toolbars. The layout for the ListView rows in the Navigation Drawer is given below. list_view_item_row.xml

<RelativeLayout xmlns:android="https://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="Item Name"
        android:textColor="@android:color/black"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        />

</RelativeLayout>

The navigation drawer items are put in a string array in the strings.xml file as shown below. strings.xml

<string-array name="navigation_drawer_items_array">
        <item>Connect</item>
        <item>Fixtures</item>
        <item>Table</item>
    </string-array>

The DataModel.java class is used to define the objects for the drawer list items. DataModel.java

package com.journaldev.navigationdrawer;

public class DataModel {

    public int icon;
    public String name;

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

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

The drawer items are stored in the form of a ListView. Hence we need to use an Adapter Class to provide that data to the activity class. DrawerItemCustomAdapter.java

package com.journaldev.navigationdrawer;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class DrawerItemCustomAdapter extends ArrayAdapter<DataModel> {

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

    public DrawerItemCustomAdapter(Context mContext, int layoutResourceId, DataModel[] 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);

        DataModel folder = data[position];


        imageViewIcon.setImageResource(folder.icon);
        textViewName.setText(folder.name);

        return listItem;
    }
}

The MainActivity.java source code is given below. MainActivity.java

package com.journaldev.navigationdrawer;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

public class MainActivity extends AppCompatActivity {

    private String[] mNavigationDrawerItemTitles;
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    Toolbar toolbar;
    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
    android.support.v7.app.ActionBarDrawerToggle mDrawerToggle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTitle = mDrawerTitle = getTitle();
        mNavigationDrawerItemTitles= getResources().getStringArray(R.array.navigation_drawer_items_array);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        setupToolbar();

        DataModel[] drawerItem = new DataModel[3];

        drawerItem[0] = new DataModel(R.drawable.connect, "Connect");
        drawerItem[1] = new DataModel(R.drawable.fixtures, "Fixtures");
        drawerItem[2] = new DataModel(R.drawable.table, "Table");
        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
        getSupportActionBar().setHomeButtonEnabled(true);

        DrawerItemCustomAdapter adapter = new DrawerItemCustomAdapter(this, R.layout.list_view_item_row, drawerItem);
        mDrawerList.setAdapter(adapter);
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        setupDrawerToggle();

    }

    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 ConnectFragment();
                break;
            case 1:
                fragment = new FixturesFragment();
                break;
            case 2:
                fragment = new TableFragment();
                break;

            default:
                break;
        }

        if (fragment != null) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

            mDrawerList.setItemChecked(position, true);
            mDrawerList.setSelection(position);
            setTitle(mNavigationDrawerItemTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);

        } else {
            Log.e("MainActivity", "Error in creating fragment");
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

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

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

    void setupToolbar(){
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
    }

    void setupDrawerToggle(){
        mDrawerToggle = new android.support.v7.app.ActionBarDrawerToggle(this,mDrawerLayout,toolbar,R.string.app_name, R.string.app_name);
        //This is necessary to change the icon of the Drawer Toggle upon state change.
        mDrawerToggle.syncState();
    }
}

In the above code getSupportActionBar().setDisplayHomeAsUpEnabled(false); is used to hide the default back button. In this code we’ve used a DrawerItemClickListener Class that loads the respective fragment of the list item clicked using a FragmentManager. Also the the title of the ToolBar is changed to the list item clicked using setTitle(mNavigationDrawerItemTitles[position]);. The fragment classes and their respective layouts are given below. ConnectFragment.java

package com.journaldev.navigationdrawer;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class ConnectFragment extends Fragment {

    public ConnectFragment() {
    }

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

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

        return rootView;
    }

}

The layout of the above fragment is defined below. fragment_connect.xml

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <TextView
        android:id="@+id/label"
        android:layout_alignParentTop="true"
        android:layout_marginTop="100dp"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:textSize="45dp"
        android:text="Connect"
        android:textStyle="bold"/>

    <TextView
        android:layout_below="@id/label"
        android:layout_centerInParent="true"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="12dp"
        android:layout_marginTop="10dp"
        android:gravity="center_horizontal"
        android:text="Edit fragment_connect.xml to change the appearance"
        android:id="@+id/textView2" />

</RelativeLayout>

The other two items are defined in exactly the same way as above hence we’re skipping it here.

Below is the output produced by our navigation drawer android example application. android navigation drawer example This brings an end to android navigation drawer example tutorial. You can download the final Android Navigation Drawer Project from the below link.

Download Android Navigation Drawer Example Project

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Anupam Chugh

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
March 23, 2021

Sir,how to open navigation drawer using button(our custom button created in mainActivity xml file) in mainActivity.

- Hrutik

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    July 19, 2020

    This was a nice tutorial helps me a lot but the code was almost 6 years old so i’ve to updated and changes old libraryes but works perfectly, thanks a lot …

    - Lexo Polka

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      May 30, 2020

      I have made a updated Bottom navigation and Navigation Drawer together on a same screen http://www.androidcoding.in/2020/05/21/android-bottom-navigation-and-navigation-drawer-part-1/

      - ramesh

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        April 30, 2019

        how can i add header in it. if i add header it repeated again and again

        - Ayush

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          February 20, 2019

          hi I am shameem Please resolve this error in App 2019-02-20 18:06:13.889 2415-2415/com.example.newnavigation E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.newnavigation, PID: 2415 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.newnavigation/com.example.newnavigation.MainActivity}: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead. at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2747) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2808) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:165) at android.app.ActivityThread.main(ActivityThread.java:6375) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802) Caused by: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead. at android.support.v7.app.AppCompatDelegateImpl.setSupportActionBar(AppCompatDelegateImpl.java:345) at android.support.v7.app.AppCompatActivity.setSupportActionBar(AppCompatActivity.java:130) at com.example.newnavigation.MainActivity.setupToolbar(MainActivity.java:121) at com.example.newnavigation.MainActivity.onCreate(MainActivity.java:35) at android.app.Activity.performCreate(Activity.java:6845) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2700) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2808)  at android.app.ActivityThread.-wrap12(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1541)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:165)  at android.app.ActivityThread.main(ActivityThread.java:6375)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)

          - Shameem

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            September 18, 2018

            How can I add a home button in addition to those connect,fragment… nd onclick it should direct me to the home page!! -Thanks

            - Alessandro vikram

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              July 15, 2018

              can you post tablefragment and fixturesfragment java file

              - aniket

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                January 25, 2018

                01/25 11:19:08: Launching app $ adb shell am start -n “com.example…navigation/com.example…navigation.MainActivity” -a android.intent.action.MAIN -c android.intent.category.LAUNCHER Connected to process 5828 on device emulator-5554 Application terminated. I’m having this error program is not running properly–it is showing Unfortunately stopped

                - Shara

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  September 24, 2017

                  How do i set the first fragment to open when i start the app instead of the blank fragment

                  - Mridul Agarwal

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    August 16, 2017

                    i need to start navigation below the appbar,what change i need to do in your project

                    - waqar

                      Try DigitalOcean for free

                      Click below to sign up and get $200 of credit to try our products over 60 days!

                      Sign up

                      Join the Tech Talk
                      Success! Thank you! Please check your email for further details.

                      Please complete your information!

                      Become a contributor for community

                      Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                      DigitalOcean Documentation

                      Full documentation for every DigitalOcean product.

                      Resources for startups and SMBs

                      The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                      Get our newsletter

                      Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                      New accounts only. By submitting your email you agree to our Privacy Policy

                      The developer cloud

                      Scale up as you grow — whether you're running one virtual machine or ten thousand.

                      Get started for free

                      Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                      *This promotional offer applies to new accounts only.