Monday, 26 December 2016

Android: Creating a Custom Navigation Drawer

The navigation drawer is a panel that displays the app’s main navigation options on the left edge of the screen. It is hidden most of the time, but is revealed when the user swipes a finger from the left edge of the screen or, while at the top level of the app, the user touches the app icon in the action bar.
This post describes how to implement a Navigation Drawer using DrawerLayout a few simple steps.

1. Create a Drawer Layout:
    Create a file under res/layout/ folder named as activity_home.xml:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/top_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

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

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/toolbar">

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

        </FrameLayout>

        <!-- The navigation drawer -->
        <ListView
            android:id="@+id/left_drawer"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:background="@color/colorPrimaryDark"
            android:choiceMode="singleChoice"
            android:divider="@android:color/white"
            android:dividerHeight="0.5dp" />

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

2. Create a Toolbar layout for your app's actionbar:
    Create a file under res/layout/ folder named as layout_toolbar.xml to show the home button animation as suggested in Material design:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimaryDark">

    <TextView
        android:id="@+id/toolbar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Title"
        android:textAlignment="center"
        android:textAppearance="@android:style/TextAppearance.Material.Widget.Toolbar.Title"
        android:textColor="@android:color/white" />
</android.support.v7.widget.Toolbar>

3. Initialize your drawer list:
    Create a class named as HomeActivity.java and use the following code snippet:

public class HomeActivity extends AppCompatActivity {
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;
    ArrayList<NavigationDrawerItemPOJO> pojoArrayList;
    Toolbar toolbar;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
     
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        pojoArrayList = new ArrayList<>();
        NavigationDrawerItemPOJO nav = new NavigationDrawerItemPOJO();
        nav.setIcon(R.mipmap.ic_launcher);
        nav.setName("Name 1");
        pojoArrayList.add(nav);
       
        mDrawerList.setAdapter(new NavigationDrawerAdapter(this, R.layout.item_navigation_drawer, pojoArrayList));

        // Set the list's click listener
        mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                Toast.makeText(getApplicationContext(), "Item clicked: " + position, Toast.LENGTH_SHORT).show();
                mDrawerLayout.closeDrawer(mDrawerList);
            }
        });
       .. .. ..
    }
}


4. Setup your drawer layout:

public class HomeActivity extends AppCompatActivity {
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;
    ArrayList<NavigationDrawerItemPOJO> pojoArrayList;
    Toolbar toolbar;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        initToolbar();

.........

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, 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);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                syncState();
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                syncState();
            }
        };

        // Set the drawer toggle as the DrawerListener
        mDrawerLayout.addDrawerListener(mDrawerToggle);
        mDrawerToggle.syncState();
    }

    //Set the custom toolbar
    public void initToolbar() {
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        if (toolbar != null) {
            setSupportActionBar(toolbar);
        }
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        TextView txtvw = (TextView) findViewById(R.id.toolbar_title);
        txtvw.setText("Nishant");
    }
.....
}

5. Create your drawer adapter and drawer item POJO:

public class NavigationDrawerAdapter extends ArrayAdapter<NavigationDrawerItemPOJO> {
        private final Context context;
        private final int layoutResourceId;
        private ArrayList<NavigationDrawerItemPOJO> arrayList;

        public NavigationDrawerAdapter(Context context, int layoutResourceId,
                                                     ArrayList<NavigationDrawerItemPOJO> arrayList) {
            super(context, layoutResourceId, arrayList);
            this.context = context;
            this.layoutResourceId = layoutResourceId;
            this.arrayList = arrayList;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            View v = inflater.inflate(layoutResourceId, parent, false);
            ImageView imageView = (ImageView) v.findViewById(R.id.navDrawerImageView);
            TextView textView = (TextView) v.findViewById(R.id.navDrawerTextView);
            NavigationDrawerItemPOJO choice = arrayList.get(position);
            imageView.setImageResource(choice.getIcon());
            textView.setText(choice.getName());
            return v;
        }
    }

    public class NavigationDrawerItemPOJO {
        public int getIcon() {
            return icon;
        }

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

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int icon;
        public String name;

        public NavigationDrawerItemPOJO() {
        }
   }

That's all..!!
After this your home activity will look something like this:

HomeActivity.java
 
public class HomeActivity extends AppCompatActivity {
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;
    ArrayList<NavigationDrawerItemPOJO> pojoArrayList;
    Toolbar toolbar;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        initToolbar();
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        pojoArrayList = new ArrayList<>();
        NavigationDrawerItemPOJO nav = new NavigationDrawerItemPOJO();
        nav.setIcon(R.mipmap.ic_launcher);
        nav.setName("Name 1");
        pojoArrayList.add(nav);
        NavigationDrawerItemPOJO nav1 = new NavigationDrawerItemPOJO();
        nav1.setIcon(R.mipmap.ic_launcher);
        nav1.setName("Name 2");
        pojoArrayList.add(nav1);
        mDrawerList.setAdapter(new NavigationDrawerAdapter(this, R.layout.item_navigation_drawer, pojoArrayList));

        // Set the list's click listener
        mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                Toast.makeText(getApplicationContext(), "Item clicked: " + position, Toast.LENGTH_SHORT).show();
                mDrawerLayout.closeDrawer(mDrawerList);
            }
        });

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, 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);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                syncState();
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                syncState();
            }
        };

        // Set the drawer toggle as the DrawerListener
        mDrawerLayout.addDrawerListener(mDrawerToggle);
        mDrawerToggle.syncState();
    }

    //Set the custom toolbar
    public void initToolbar() {
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        if (toolbar != null) {
            setSupportActionBar(toolbar);
        }
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        TextView txtvw = (TextView) findViewById(R.id.toolbar_title);
        txtvw.setText("Nishant");
    }

    public class NavigationDrawerAdapter extends ArrayAdapter<NavigationDrawerItemPOJO> {
        private final Context context;
        private final int layoutResourceId;
        private ArrayList<NavigationDrawerItemPOJO> arrayList;

        public NavigationDrawerAdapter(Context context, int layoutResourceId, ArrayList<NavigationDrawerItemPOJO> arrayList) {
            super(context, layoutResourceId, arrayList);
            this.context = context;
            this.layoutResourceId = layoutResourceId;
            this.arrayList = arrayList;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            View v = inflater.inflate(layoutResourceId, parent, false);
            ImageView imageView = (ImageView) v.findViewById(R.id.navDrawerImageView);
            TextView textView = (TextView) v.findViewById(R.id.navDrawerTextView);
            NavigationDrawerItemPOJO choice = arrayList.get(position);
            imageView.setImageResource(choice.getIcon());
            textView.setText(choice.getName());
            return v;
        }
    }

    public class NavigationDrawerItemPOJO {
        public int getIcon() {
            return icon;
        }

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

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int icon;
        public String name;

        public NavigationDrawerItemPOJO() {
        }
    }
}


Run it and enjoy your app with a drawer that has material design drawer animation.
In this post your drawer will slide below the actionBar, just to show the animation. You can have it over the actionBar as well.

Share, Comment and Reply if any issues.


2 comments:

  1. Well explained .....but I need the drawer from Right to Left instead of the default one(Left to right). Please help....

    ReplyDelete
  2. In the activity_home.xml file, in the ListView just change android:layout_gravity="start" to android:layout_gravity="right".
    There you go.

    ReplyDelete