차근차근/Android

네비게이션 드로어 Navigation Drawer

예쁜꽃이피었으면 2015. 2. 4. 10:32

http://www.tutecentral.com/android-custom-navigation-drawer/


NavigationDrawerExample.zip







Android Custom Navigation Drawer

Navigation Drawer with Advance Customizations

Custom Navigaton Drawer

Android has different navigation options  available to navigate between views in an android application. Navigation drawer is the the one of the best option out of them. In this tutorial I’ll try to demonstrate how implement a navigation drawer according to your customizations. If look at the navigation drawer sample application at developer.android.com website, you can see it is a listview  used to navigate through different fragments. As you can see  in the below screenshot it simply list down the names of different planets and when we click on a single item it will close the navigation drawer and it will load an image of that planet.

Navigation Drawer Sample App Navigation
Navigation Drawer Sample App Navigation

Most of the google apps use navigation drawer. But those navigation drawers are customized by developers according to application requirement and usability. But android developer guide will not show you how to customize the navigation drawer according to users need. See below image to get an idea about custom navigation drawers.

Example Custom Navigation Drawer Apps
Example Custom Navigation Drawer Apps

In this tutorial I’ll show you how to create a custom navigation drawer. First part of this tutorial I’ll cover the basic implementation  of navigation drawer from second part onwards I’ll show you how to customize it.If you know basic implementation then skip this part and refer the customization part. You can find source code and video demonstration of this tutorial at end of this page.

Demo Video

Basic Implementation of Navigation Drawer

Step 1 : Download Resources

Before you start you need to download below resources.

Resource Pack : Download the Resource Pack

Now extract the “NavigationDrawer_ResourcePack.zip” file you download.

Step 2 : Create a Project and Setup the Project

Create a new android project. Give the  Application Name as “NavigationDrawer“, Package Name as “com.tutecentral.navigationdrawer”  and select the Minimum Required SDK as “API 14: Android 4.0 (ICS)“. I’ll keep the Activity Name as “MainActivity” and Layout Name as “activity_main“.

Copy and paste all drawable files in “NavigationDrawer_ResourcePack -> app_drawables” folder into application drawables. Now we done with project setup. 

Step 3 : Create Layout Files and Fragment

For demonstration purposes I’ll use three fragments to navigate between navigation drawer items. Okay Now create four layout files respectively “custom_drawer_item“, “fragment_layout_one“, “fragment_layout_two” and “fragment_layout_three“.  “custom_drawer_item” is used for build a custom listview and other three fragment layout used for Fragment Views. 

Steps to Create a New Layout File.

  1. Right Click on the “res -> layout” folder
  2. Go to “New -> Android XML File
  3. Select the Resource Type as “Layout
  4. Give a File Name
  5. Select the Root Element (Most of the time it is a Layout type)
  6. Click “Finish” button

Open  “activity_main.xml” file in “res->layout” folder. Copy and paste below code into activity_main.xml layout file. Dont forget to add the v4 support library (android-support-v4.jar) to lib folder in the project.

activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <!-- As the main content view, the view below consumes the entire
         space available using match_parent in both dimensions. -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
 
    <!-- android:layout_gravity="start" tells DrawerLayout to treat
         this as a sliding drawer on the left side for left-to-right
         languages and on the right side for right-to-left languages.
         The drawer is given a fixed width in dp and extends the full height of
         the container. A solid background is used for contrast
         with the content view. -->
 
    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#ffff"/>
</android.support.v4.widget.DrawerLayout>

Steps to Add Support Library to Application

  1. Goto Following Path “Your Android SDK Drive” \sdk\extras\android\support\v4
  2. Copy “android-support-v4.jar” file
  3. Paste it in “lib” folder in your application

Now copy and paste the below xml to “custom_drawer_item.xml” layout file. Be aware this xml file will be change when we creating a custom navigation  drawer

custom_drawer_item.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?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="fill_parent" >
 
    <LinearLayout
      android:id="@+id/itemLayout"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:layout_alignParentLeft="true"
      android:orientation="vertical"
 
      android:layout_marginTop="0dp"
      android:background="?android:attr/activatedBackgroundIndicator"
     >
 
              <LinearLayout
 
                  android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:minHeight="55dp"
                 >
 
                  <ImageView
                      android:id="@+id/drawer_icon"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      />
 
                  <TextView
                      android:id="@+id/drawer_itemName"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:textAppearance="?android:attr/textAppearanceLarge"
 
                       />
              </LinearLayout>
 
               <View
      android:layout_width="match_parent"
      android:layout_height="1dp"
      android:layout_marginBottom="1dp"
      android:layout_marginTop="1dp"
      android:layout_marginLeft="10dp"
      android:layout_marginRight="10dp"
      android:background="#DADADC"
 
       ></View>
 
    </LinearLayout>
 
</RelativeLayout>

Now copy and paste the below xml code to all three fragment xml files. Dont forget to change the id attribute values in other two layout file. See the comment in the code.

fragment_layout_one.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    >
 
    <!--
    **************************IMPORTANT***********************************
     change this id attribute values as "frag2_icon" and "frag2_text" for
     fragment_layout_two.xml and "frag3_icon" and "frag3_text" for
     fragment_layout_three.xml
    **********************************************************************
      -->
 
    <ImageView
        android:id="@+id/frag1_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
      />
 
    <TextView
        android:id="@+id/frag1_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:textAppearance="?android:attr/textAppearanceLarge" />
 
</LinearLayout>

Next add following item to “strings.xml”  file in “res-> values” folder

Update strings.xml
1
2
<string name="drawer_open">Open drawer</string>
<string name="drawer_close">Close drawer</string>

Now we are done with xml files.

Step 4 : Create Fragment Class and Custom ListView Adapter

Next task is to create fragment class for all three layout files and implement a custom listview adapter.  Create five class list down below

  • CustomDrawerAdapter
  • DrawerItem
  • FragmentOne
  • FragmentTwo
  • FragmentThree

Steps to Create a New Class File.

  1. Right Click on the “src-> com.tutecentral.navigationdrawer” package
  2. Go to “New -> Class
  3. Give a Class Name
  4. Click “Finish” button

Copy and paste below codes to FragmentOne, FragmentTwo and FragmentThree class respectively. All these class are subclass of Fragment Class

FragmentOne.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.tutecentral.navigationdrawer;
 
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
 
public class FragmentOne extends Fragment {
 
      ImageView ivIcon;
      TextView tvItemName;
 
      public static final String IMAGE_RESOURCE_ID = "iconResourceID";
      public static final String ITEM_NAME = "itemName";
 
      public FragmentOne() {
 
      }
 
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
                  Bundle savedInstanceState) {
 
            View view = inflater.inflate(R.layout.fragment_layout_one, container,
                        false);
 
            ivIcon = (ImageView) view.findViewById(R.id.frag1_icon);
            tvItemName = (TextView) view.findViewById(R.id.frag1_text);
 
            tvItemName.setText(getArguments().getString(ITEM_NAME));
            ivIcon.setImageDrawable(view.getResources().getDrawable(
                        getArguments().getInt(IMAGE_RESOURCE_ID)));
            return view;
      }
 
}
FragmentTwo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.tutecentral.navigationdrawer;
 
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
 
public class FragmentTwo   extends Fragment {
 
      ImageView ivIcon;
      TextView tvItemName;
 
      public static final String IMAGE_RESOURCE_ID = "iconResourceID";
      public static final String ITEM_NAME = "itemName";
 
      public FragmentTwo()
      {
 
      }
 
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
                  Bundle savedInstanceState) {
 
            View view=inflater.inflate(R.layout.fragment_layout_two,container, false);
 
            ivIcon=(ImageView)view.findViewById(R.id.frag2_icon);
            tvItemName=(TextView)view.findViewById(R.id.frag2_text);
 
            tvItemName.setText(getArguments().getString(ITEM_NAME));
            ivIcon.setImageDrawable(view.getResources().getDrawable(
                        getArguments().getInt(IMAGE_RESOURCE_ID)));
            return view;
      }
 
}
FragmentThree.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.tutecentral.navigationdrawer;
 
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
 
public class FragmentThree extends Fragment {
 
      ImageView ivIcon;
      TextView tvItemName;
 
      public static final String IMAGE_RESOURCE_ID = "iconResourceID";
      public static final String ITEM_NAME = "itemName";
 
      public FragmentThree() {
 
      }
 
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
                  Bundle savedInstanceState) {
 
            View view = inflater.inflate(R.layout.fragment_layout_three, container,
                        false);
 
            ivIcon = (ImageView) view.findViewById(R.id.frag3_icon);
            tvItemName = (TextView) view.findViewById(R.id.frag3_text);
 
            tvItemName.setText(getArguments().getString(ITEM_NAME));
            ivIcon.setImageDrawable(view.getResources().getDrawable(
                        getArguments().getInt(IMAGE_RESOURCE_ID)));
            return view;
      }
 
}

Next open the “DrawerItem.java” class and update it as below code. This class also be upgrade when creating the custom navigation drawer

DrawerItem.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.tutecentral.navigationdrawer;
 
public class DrawerItem {
 
      String ItemName;
      int imgResID;
 
      public DrawerItem(String itemName, int imgResID) {
            super();
            ItemName = itemName;
            this.imgResID = imgResID;
      }
 
      public String getItemName() {
            return ItemName;
      }
      public void setItemName(String itemName) {
            ItemName = itemName;
      }
      public int getImgResID() {
            return imgResID;
      }
      public void setImgResID(int imgResID) {
            this.imgResID = imgResID;
      }
 
}

Now we can create a custom adapter for drawer listview. Open the “CustomDrawerAdapter.java” class and update the class according to below code. Keep in mind class will be update when customizing the navigation drawer.

CustomDrawerAdapter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package com.tutecentral.navigationdrawer;
 
import java.util.List;
 
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 CustomDrawerAdapter extends ArrayAdapter<DrawerItem> {
 
      Context context;
      List<DrawerItem> drawerItemList;
      int layoutResID;
 
      public CustomDrawerAdapter(Context context, int layoutResourceID,
                  List<DrawerItem> listItems) {
            super(context, layoutResourceID, listItems);
            this.context = context;
            this.drawerItemList = listItems;
            this.layoutResID = layoutResourceID;
 
      }
 
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
 
            DrawerItemHolder drawerHolder;
            View view = convertView;
 
            if (view == null) {
                  LayoutInflater inflater = ((Activity) context).getLayoutInflater();
                  drawerHolder = new DrawerItemHolder();
 
                  view = inflater.inflate(layoutResID, parent, false);
                  drawerHolder.ItemName = (TextView) view
                              .findViewById(R.id.drawer_itemName);
                  drawerHolder.icon = (ImageView) view.findViewById(R.id.drawer_icon);
 
                  view.setTag(drawerHolder);
 
            else {
                  drawerHolder = (DrawerItemHolder) view.getTag();
 
            }
 
            DrawerItem dItem = (DrawerItem) this.drawerItemList.get(position);
 
            drawerHolder.icon.setImageDrawable(view.getResources().getDrawable(
                        dItem.getImgResID()));
            drawerHolder.ItemName.setText(dItem.getItemName());
 
            return view;
      }
 
      private static class DrawerItemHolder {
            TextView ItemName;
            ImageView icon;
      }
}

Okay we are done with the adapter class now we need to update the “MainActivity.java” class. This class I’ll update step by step so you can understand how it works.  Open the MainActivity.java class.

First declare the below objects.

1
2
3
4
5
6
7
8
9
10
11
12
public class MainActivity extends Activity {
 
      private DrawerLayout mDrawerLayout;
      private ListView mDrawerList;
      private ActionBarDrawerToggle mDrawerToggle;
 
      private CharSequence mDrawerTitle;
      private CharSequence mTitle;
      CustomDrawerAdapter adapter;
 
      List<DrawerItem> dataList;
...// dont copy this line

Now initialize the declared object in onCreate() method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
      @Override
      protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
 
            // Initializing
            dataList = new ArrayList<DrawerItem>();
            mTitle = mDrawerTitle = getTitle();
            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
            mDrawerList = (ListView) findViewById(R.id.left_drawer);
 
            mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
                        GravityCompat.START);
...

Now add item to the “dataList” object. So those list items will display in the drawer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Add Drawer Item to dataList
            // Add Drawer Item to dataList
            dataList.add(new DrawerItem("Message", R.drawable.ic_action_email));
            dataList.add(new DrawerItem("Likes", R.drawable.ic_action_good));
            dataList.add(new DrawerItem("Games", R.drawable.ic_action_gamepad));
            dataList.add(new DrawerItem("Lables", R.drawable.ic_action_labels));
            dataList.add(new DrawerItem("Search", R.drawable.ic_action_search));
            dataList.add(new DrawerItem("Cloud", R.drawable.ic_action_cloud));
            dataList.add(new DrawerItem("Camara", R.drawable.ic_action_camera));
            dataList.add(new DrawerItem("Video", R.drawable.ic_action_video));
            dataList.add(new DrawerItem("Groups", R.drawable.ic_action_group));
            dataList.add(new DrawerItem("Import & Export",
                        R.drawable.ic_action_import_export));
            dataList.add(new DrawerItem("About", R.drawable.ic_action_about));
            dataList.add(new DrawerItem("Settings", R.drawable.ic_action_settings));
            dataList.add(new DrawerItem("Help", R.drawable.ic_action_help));
...

Now initialize and set the adapter to the  drawer listview

1
2
3
4
5
6
...
            adapter = new CustomDrawerAdapter(this, R.layout.custom_drawer_item,
                        dataList);
 
            mDrawerList.setAdapter(adapter);
...

Now create a method in MainActivity.java to select the correct fragment. I’ll call this method “SelectItem()” which will take a one integer parameter, to identify the position of the selected item. In this method I’ll use a “switch-case” statement to get correct fragment. I created only three fragments for demonstration purpose. You can do this even using a single fragment class.

SelectItem(int position) in MainActivity.java class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
public void SelectItem(int possition) {
 
            Fragment fragment = null;
            Bundle args = new Bundle();
            switch (possition) {
            case 0:
                  fragment = new FragmentOne();
                  args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 1:
                  fragment = new FragmentTwo();
                  args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 2:
                  fragment = new FragmentThree();
                  args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 3:
                  fragment = new FragmentOne();
                  args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 4:
                  fragment = new FragmentTwo();
                  args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 5:
                  fragment = new FragmentThree();
                  args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 6:
                  fragment = new FragmentOne();
                  args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 7:
                  fragment = new FragmentTwo();
                  args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 8:
                  fragment = new FragmentThree();
                  args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 9:
                  fragment = new FragmentOne();
                  args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 10:
                  fragment = new FragmentTwo();
                  args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 11:
                  fragment = new FragmentThree();
                  args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 12:
                  fragment = new FragmentOne();
                  args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            default:
                  break;
            }
 
            fragment.setArguments(args);
            FragmentManager frgManager = getFragmentManager();
            frgManager.beginTransaction().replace(R.id.content_frame, fragment)
                        .commit();
 
            mDrawerList.setItemChecked(possition, true);
            setTitle(dataList.get(possition).getItemName());
            mDrawerLayout.closeDrawer(mDrawerList);
 
      }

Now you need to override following methods and update those methods as following code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Override
public void setTitle(CharSequence title) {
      mTitle = title;
      getActionBar().setTitle(mTitle);
}
 
@Override
protected void onPostCreate(Bundle savedInstanceState) {
      super.onPostCreate(savedInstanceState);
      // Sync the toggle state after onRestoreInstanceState has occurred.
      mDrawerToggle.syncState();
}
 
@Override
public boolean onOptionsItemSelected(MenuItem item) {
      // The action bar home/up action should open or close the drawer.
      // ActionBarDrawerToggle will take care of this.
      if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
      }
 
      return false;
}
 
@Override
public void onConfigurationChanged(Configuration newConfig) {
      super.onConfigurationChanged(newConfig);
      // Pass any configuration change to the drawer toggles
      mDrawerToggle.onConfigurationChanged(newConfig);
}

Now we need to create custom “OnItemClickListener“. To do that create a another class called “DrawerItemClickListener” inside MainActivity.java.  “DrawerItemClickListener” class implements the  “OnItemClickListener“. 

DrawerItemClickListener
1
2
3
4
5
6
7
8
9
private class DrawerItemClickListener implements
            ListView.OnItemClickListener {
      @Override
      public void onItemClick(AdapterView<?> parent, View view, int position,
                  long id) {
            SelectItem(position);
 
      }
}

Now came back to OnCreate() method and set the OnItemClickListener as below

1
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

Now we need to enable the HomeUpButton for action bar and set the toggle to the Drawer Layout

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
 
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
            R.drawable.ic_drawer, R.string.drawer_open,
            R.string.drawer_close) {
      public void onDrawerClosed(View view) {
            getActionBar().setTitle(mTitle);
            invalidateOptionsMenu(); // creates call to
                                                      // onPrepareOptionsMenu()
      }
 
      public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(mDrawerTitle);
            invalidateOptionsMenu(); // creates call to
                                                      // onPrepareOptionsMenu()
      }
};
 
mDrawerLayout.setDrawerListener(mDrawerToggle);
 
if (savedInstanceState == null) {
      SelectItem(0);
}

Now our MainActivity.java class is completed. Below you can see the complete code for MainActivity.java class

MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
package com.tutecentral.navigationdrawer;
 
import java.util.ArrayList;
import java.util.List;
 
import android.os.Bundle;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.res.Configuration;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
 
public class MainActivity extends Activity {
 
      private DrawerLayout mDrawerLayout;
      private ListView mDrawerList;
      private ActionBarDrawerToggle mDrawerToggle;
 
      private CharSequence mDrawerTitle;
      private CharSequence mTitle;
      CustomDrawerAdapter adapter;
 
      List<DrawerItem> dataList;
 
      @Override
      protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
 
            // Initializing
            dataList = new ArrayList<DrawerItem>();
            mTitle = mDrawerTitle = getTitle();
            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
            mDrawerList = (ListView) findViewById(R.id.left_drawer);
 
            mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
                        GravityCompat.START);
 
            // Add Drawer Item to dataList
            dataList.add(new DrawerItem("Message", R.drawable.ic_action_email));
            dataList.add(new DrawerItem("Likes", R.drawable.ic_action_good));
            dataList.add(new DrawerItem("Games", R.drawable.ic_action_gamepad));
            dataList.add(new DrawerItem("Lables", R.drawable.ic_action_labels));
            dataList.add(new DrawerItem("Search", R.drawable.ic_action_search));
            dataList.add(new DrawerItem("Cloud", R.drawable.ic_action_cloud));
            dataList.add(new DrawerItem("Camara", R.drawable.ic_action_camera));
            dataList.add(new DrawerItem("Video", R.drawable.ic_action_video));
            dataList.add(new DrawerItem("Groups", R.drawable.ic_action_group));
            dataList.add(new DrawerItem("Import & Export",
                        R.drawable.ic_action_import_export));
            dataList.add(new DrawerItem("About", R.drawable.ic_action_about));
            dataList.add(new DrawerItem("Settings", R.drawable.ic_action_settings));
            dataList.add(new DrawerItem("Help", R.drawable.ic_action_help));
 
            adapter = new CustomDrawerAdapter(this, R.layout.custom_drawer_item,
                        dataList);
 
            mDrawerList.setAdapter(adapter);
 
            mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
 
            getActionBar().setDisplayHomeAsUpEnabled(true);
            getActionBar().setHomeButtonEnabled(true);
 
            mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                        R.drawable.ic_drawer, R.string.drawer_open,
                        R.string.drawer_close) {
                  public void onDrawerClosed(View view) {
                        getActionBar().setTitle(mTitle);
                        invalidateOptionsMenu(); // creates call to
                                                                  // onPrepareOptionsMenu()
                  }
 
                  public void onDrawerOpened(View drawerView) {
                        getActionBar().setTitle(mDrawerTitle);
                        invalidateOptionsMenu(); // creates call to
                                                                  // onPrepareOptionsMenu()
                  }
            };
 
            mDrawerLayout.setDrawerListener(mDrawerToggle);
 
            if (savedInstanceState == null) {
                  SelectItem(0);
            }
 
      }
 
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
      }
 
      public void SelectItem(int possition) {
 
            Fragment fragment = null;
            Bundle args = new Bundle();
            switch (possition) {
            case 0:
                  fragment = new FragmentOne();
                  args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 1:
                  fragment = new FragmentTwo();
                  args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 2:
                  fragment = new FragmentThree();
                  args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 3:
                  fragment = new FragmentOne();
                  args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 4:
                  fragment = new FragmentTwo();
                  args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 5:
                  fragment = new FragmentThree();
                  args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 6:
                  fragment = new FragmentOne();
                  args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 7:
                  fragment = new FragmentTwo();
                  args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 8:
                  fragment = new FragmentThree();
                  args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 9:
                  fragment = new FragmentOne();
                  args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 10:
                  fragment = new FragmentTwo();
                  args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 11:
                  fragment = new FragmentThree();
                  args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            case 12:
                  fragment = new FragmentOne();
                  args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                              .getItemName());
                  args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                              .getImgResID());
                  break;
            default:
                  break;
            }
 
            fragment.setArguments(args);
            FragmentManager frgManager = getFragmentManager();
            frgManager.beginTransaction().replace(R.id.content_frame, fragment)
                        .commit();
 
            mDrawerList.setItemChecked(possition, true);
            setTitle(dataList.get(possition).getItemName());
            mDrawerLayout.closeDrawer(mDrawerList);
 
      }
 
      @Override
      public void setTitle(CharSequence title) {
            mTitle = title;
            getActionBar().setTitle(mTitle);
      }
 
      @Override
      protected void onPostCreate(Bundle savedInstanceState) {
            super.onPostCreate(savedInstanceState);
            // Sync the toggle state after onRestoreInstanceState has occurred.
            mDrawerToggle.syncState();
      }
 
      @Override
      public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            // Pass any configuration change to the drawer toggles
            mDrawerToggle.onConfigurationChanged(newConfig);
      }
 
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
            // The action bar home/up action should open or close the drawer.
            // ActionBarDrawerToggle will take care of this.
            if (mDrawerToggle.onOptionsItemSelected(item)) {
                  return true;
            }
 
            return false;
      }
 
        private class DrawerItemClickListener implements
                  ListView.OnItemClickListener {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                        long id) {
                  SelectItem(position);
 
            }
      }
 
}

Now we are done with the “Basic Implementation of Navigation Drawer”  you can run this application now to see the output of the basic drawer.

Basic Navigation Drawer
Basic Navigation Drawer

You can download the basic navigation drawer sample code at end of this tutorial.

Customizing the Navigation Drawer

Now we can update this basic implementation of navigation drawer  to more customized navigation drawer. As I mention  we have to update existing class  and xml layouts to do this. I’ll customize the navigation drawer by adding aSpinnerView to select the user account and add some headers to the  listview to categorize the list items (like youtube app).

Step 5 : Creating Custom Spinner View

Create a xml layout called “custom_spinner_item”  file in “res->layout“. Add the following xml code to the layout file. This is the layout file passed to the custom spinner adapter.

custom_spinner_item.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
 
    <ImageView
        android:id="@+id/left_pic"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp" />
 
    <TextView
        android:id="@+id/text_main_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginTop="0dp"
        android:layout_toRightOf="@+id/left_pic"
        android:padding="0dp"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="#1d97dd"
        android:textStyle="bold" />
 
    <TextView
        android:id="@+id/sub_text_email"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/text_main_name"
        android:layout_marginLeft="5dip"
        android:layout_toRightOf="@+id/left_pic"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="#777777" />
 
</RelativeLayout>

Now create below two class for custom adapter and layout model

  • CustomSpinnerAdapter
  • SpinnerItem

Now open the SpinnerItem.java and add the below code to the class file.

SpinnerItem.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.tutecentral.navigationdrawer;
 
public class SpinnerItem {
 
      int drawableResID;
      String name;
      String email;
 
      public SpinnerItem(int drawableResID, String name, String email) {
            super();
            this.drawableResID = drawableResID;
            this.name = name;
            this.email = email;
      }
 
      public int getDrawableResID() {
            return drawableResID;
      }
      public void setDrawableResID(int drawableResID) {
            this.drawableResID = drawableResID;
      }
      public String getName() {
            return name;
      }
      public void setName(String name) {
            this.name = name;
      }
      public String getEmail() {
            return email;
      }
      public void setEmail(String email) {
            this.email = email;
      }
 
}

Now you can use this class to create a spinner custom adapter. So open the  “CustomSpinnerAdapter.java” class and update the class according to below cording

CustomSpinnerAdapter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package com.tutecentral.navigationdrawer;
 
import java.util.List;
 
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 CustomSpinnerAdapter extends ArrayAdapter<SpinnerItem>{
 
      public CustomSpinnerAdapter(Context context, int layoutResourceID,
                  int textViewResourceId, List<SpinnerItem> spinnerDataList) {
            super(context, layoutResourceID, textViewResourceId, spinnerDataList);
 
            this.context=context;
            this.layoutResID=layoutResourceID;
            this.spinnerData=spinnerDataList;
 
      }
 
      Context context;
      int layoutResID;
      List<SpinnerItem> spinnerData;
 
      public CustomSpinnerAdapter(Context context, int layoutResourceID,
                  List<SpinnerItem> spinnerDataList) {
            super(context, layoutResourceID, spinnerDataList);
 
            this.context=context;
            this.layoutResID=layoutResourceID;
            this.spinnerData=spinnerDataList;
 
      }
 
      @Override
      public View getDropDownView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            return getCustomView(position, convertView, parent);
      }
 
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            return getCustomView(position, convertView, parent);
      }
 
      public View getCustomView(int position, View convertView, ViewGroup parent) {
 
            View row=convertView;
            SpinnerHolder holder;
 
            if(row==null)
            {
                  LayoutInflater inflater=((Activity)context).getLayoutInflater();
 
                  row=inflater.inflate(layoutResID, parent, false);
                  holder=new SpinnerHolder();
 
                  holder.userImage=(ImageView)row.findViewById(R.id.left_pic);
                  holder.name=(TextView)row.findViewById(R.id.text_main_name);
                  holder.email=(TextView)row.findViewById(R.id.sub_text_email);
 
                  row.setTag(holder);
            }
            else
            {
                  holder=(SpinnerHolder)row.getTag();
 
            }
 
            SpinnerItem spinnerItem=spinnerData.get(position);
 
            holder.userImage.setImageDrawable(row.getResources().getDrawable(spinnerItem.getDrawableResID()));
            holder.name.setText(spinnerItem.getName());
            holder.email.setText(spinnerItem.getEmail());
 
            return row;
 
      }
 
      private static class SpinnerHolder
      {
            ImageView userImage;
            TextView  name,email;
 
      }
 
}

Now we are completed the “CustomSpinnerAdapter.java” class. We can use this class in “CustomDrawerAdapter.java” to populate a spinner in the navigation drawer.

Next  update the “custom_drawer_item.xml” layout file. See the below code and update your xml file.To update replace the old xml code by below updated code.

updated custom_drawer_item.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?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="fill_parent" >
 
     <LinearLayout
        android:id="@+id/spinnerLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
      android:layout_marginTop="0dp"
         >
 
           <Spinner
                        android:id="@+id/drawerSpinner"
                        android:layout_width="fill_parent"
                        android:layout_height="0dp"
                        android:layout_weight="1" />
    </LinearLayout>
 
    <LinearLayout
        android:id="@+id/headerLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
      android:layout_marginTop="20dp"
         >
 
        <TextView
            android:id="@+id/drawerTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
 
            android:textAppearance="?android:attr/textAppearanceSmall" />
 
             <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:layout_marginBottom="1dp"
        android:layout_marginTop="1dp"
        android:background="#DADADC" ></View>
 
    </LinearLayout>
 
      <LinearLayout
        android:id="@+id/itemLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:orientation="vertical"
        android:layout_marginTop="0dp"
 
        android:background="?android:attr/activatedBackgroundIndicator"
       >
 
                <LinearLayout
 
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:minHeight="50dp"
                   >
 
                    <ImageView
                        android:id="@+id/drawer_icon"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        />
 
                    <TextView
                        android:id="@+id/drawer_itemName"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textAppearance="?android:attr/textAppearanceLarge"
 
                         />
                </LinearLayout>
 
                 <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginBottom="0dp"
        android:layout_marginTop="0dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:background="#DADADC"
         ></View>
 
      </LinearLayout>
</RelativeLayout>

Now we can do updates for other class used to create navigation drawer.

1. Updates For “DrawerItem.java” class

Updates for DrawerItem.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class DrawerItem {
 
      String ItemName;
      int imgResID;
      String title;
      boolean isSpinner;
 
...
        public DrawerItem(boolean isSpinner) {
            this(null0);
            this.isSpinner = isSpinner;
      }
 
      public DrawerItem(String title) {
            this(null0);
            this.title = title;
      }
 
...
      public String getTitle() {
            return title;
      }
      public void setTitle(String title) {
            this.title = title;
      }
 
      public boolean isSpinner() {
            return isSpinner;
      }
...
}

2. Updates for CustomDrawerAdapter.java Class

In this class changes will only happens togetView() method & DrawerItemHolder internal class. Just copy and replace the below code to the class file so you may not get any errors while updating.

Updates for CustomDrawerAdapter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
@Override
      public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
 
            DrawerItemHolder drawerHolder;
            View view = convertView;
 
            if (view == null) {
                  LayoutInflater inflater = ((Activity) context).getLayoutInflater();
                  drawerHolder = new DrawerItemHolder();
 
                  view = inflater.inflate(layoutResID, parent, false);
                  drawerHolder.ItemName = (TextView) view
                              .findViewById(R.id.drawer_itemName);
                  drawerHolder.icon = (ImageView) view.findViewById(R.id.drawer_icon);
 
                  drawerHolder.spinner = (Spinner) view
                              .findViewById(R.id.drawerSpinner);
 
                  drawerHolder.title = (TextView) view.findViewById(R.id.drawerTitle);
 
                  drawerHolder.headerLayout = (LinearLayout) view
                              .findViewById(R.id.headerLayout);
                  drawerHolder.itemLayout = (LinearLayout) view
                              .findViewById(R.id.itemLayout);
                  drawerHolder.spinnerLayout = (LinearLayout) view
                              .findViewById(R.id.spinnerLayout);
 
                  view.setTag(drawerHolder);
 
            else {
                  drawerHolder = (DrawerItemHolder) view.getTag();
 
            }
 
            DrawerItem dItem = (DrawerItem) this.drawerItemList.get(position);
 
            if (dItem.isSpinner()) {
                  drawerHolder.headerLayout.setVisibility(LinearLayout.INVISIBLE);
                  drawerHolder.itemLayout.setVisibility(LinearLayout.INVISIBLE);
                  drawerHolder.spinnerLayout.setVisibility(LinearLayout.VISIBLE);
 
                  List<SpinnerItem> userList = new ArrayList<SpinnerItem>();
 
                    userList.add(new SpinnerItem(R.drawable.user1, "Ahamed Ishak",
                              "ishakgmail.com"));
 
                  userList.add(new SpinnerItem(R.drawable.user2, "Brain Jekob",
                              "brain.jgmail.com"));
 
                  CustomSpinnerAdapter adapter = new CustomSpinnerAdapter(context,
                              R.layout.custom_spinner_item, userList);
 
                  drawerHolder.spinner.setAdapter(adapter);
 
                  drawerHolder.spinner
                              .setOnItemSelectedListener(new OnItemSelectedListener() {
 
                                    @Override
                                    public void onItemSelected(AdapterView<?> arg0,
                                                View arg1, int arg2, long arg3) {
 
                                          Toast.makeText(context, "User Changed",
                                                      Toast.LENGTH_SHORT).show();
                                    }
 
                                    @Override
                                    public void onNothingSelected(AdapterView<?> arg0) {
                                          // TODO Auto-generated method stub
 
                                    }
                              });
 
            else if (dItem.getTitle() != null) {
                  drawerHolder.headerLayout.setVisibility(LinearLayout.VISIBLE);
                  drawerHolder.itemLayout.setVisibility(LinearLayout.INVISIBLE);
                  drawerHolder.spinnerLayout.setVisibility(LinearLayout.INVISIBLE);
                  drawerHolder.title.setText(dItem.getTitle());
 
            else {
 
                  drawerHolder.headerLayout.setVisibility(LinearLayout.INVISIBLE);
                  drawerHolder.spinnerLayout.setVisibility(LinearLayout.INVISIBLE);
                  drawerHolder.itemLayout.setVisibility(LinearLayout.VISIBLE);
 
                  drawerHolder.icon.setImageDrawable(view.getResources().getDrawable(
                              dItem.getImgResID()));
                  drawerHolder.ItemName.setText(dItem.getItemName());
 
            }
            return view;
      }
 
      private static class DrawerItemHolder {
            TextView ItemName, title;
            ImageView icon;
            LinearLayout headerLayout, itemLayout, spinnerLayout;
            Spinner spinner;
      }

3. Updates for MainActivity.java class

In  OnCreate method we need call the correct constructor of the DrawerItemclass when we adding item to the dataList object and need to change theif condition  which is used to check “savedInstanceState == null“. See the below coding and update your code.

Updates for OnCreate() method in MainActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
// Add Drawer Item to dataList
            dataList.add(new DrawerItem(true)); // adding a spinner to the list
 
            dataList.add(new DrawerItem("My Favorites")); // adding a header to the list
            dataList.add(new DrawerItem("Message", R.drawable.ic_action_email));
            dataList.add(new DrawerItem("Likes", R.drawable.ic_action_good));
            dataList.add(new DrawerItem("Games", R.drawable.ic_action_gamepad));
            dataList.add(new DrawerItem("Lables", R.drawable.ic_action_labels));
 
             dataList.add(new DrawerItem("Main Options"));// adding a header to the list
            dataList.add(new DrawerItem("Search", R.drawable.ic_action_search));
            dataList.add(new DrawerItem("Cloud", R.drawable.ic_action_cloud));
            dataList.add(new DrawerItem("Camara", R.drawable.ic_action_camera));
            dataList.add(new DrawerItem("Video", R.drawable.ic_action_video));
            dataList.add(new DrawerItem("Groups", R.drawable.ic_action_group));
            dataList.add(new DrawerItem("Import & Export",
                        R.drawable.ic_action_import_export));
 
             dataList.add(new DrawerItem("Other Option")); // adding a header to the list
            dataList.add(new DrawerItem("About", R.drawable.ic_action_about));
            dataList.add(new DrawerItem("Settings", R.drawable.ic_action_settings));
            dataList.add(new DrawerItem("Help", R.drawable.ic_action_help));
...
            if (savedInstanceState == null) {
 
                  if (dataList.get(0).isSpinner()
                              & dataList.get(1).getTitle() != null) {
                        SelectItem(2);
                  else if (dataList.get(0).getTitle() != null) {
                        SelectItem(1);
                  else {
                        SelectItem(0);
                  }
            }

Next update the SelectItem() method. You need to update this according to the “dataList” item position. Fragment should be only need to change when we click in a selectable item not in header or spinner.  So change the casestatements to point correct selectable item. (Be careful you may get runtime errors if you update incorrectly.) I delete the  0,1 and 6 case statement and add new case statement for 14,15 and 16 positions .

Updates for SelectItem() method in MainActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    public void SelectItem(int possition) {
 
      Fragment fragment = null;
      Bundle args = new Bundle();
      switch (possition) {
 
      case 2:
            fragment = new FragmentThree();
            args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList
                        .get(possition).getImgResID());
            break;
      case 3:
            fragment = new FragmentOne();
            args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                        .getImgResID());
            break;
      case 4:
            fragment = new FragmentTwo();
            args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition)
                        .getImgResID());
            break;
      case 5:
            fragment = new FragmentThree();
            args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList
                        .get(possition).getImgResID());
            break;
      case 7:
            fragment = new FragmentTwo();
            args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition)
                        .getImgResID());
            break;
      case 8:
            fragment = new FragmentThree();
            args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList
                        .get(possition).getImgResID());
            break;
      case 9:
            fragment = new FragmentOne();
            args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                        .getImgResID());
            break;
      case 10:
            fragment = new FragmentTwo();
            args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition)
                        .getImgResID());
            break;
      case 11:
            fragment = new FragmentThree();
            args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList
                        .get(possition).getImgResID());
            break;
      case 12:
            fragment = new FragmentOne();
            args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                        .getImgResID());
            break;
      case 14:
            fragment = new FragmentThree();
            args.putString(FragmentThree.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentThree.IMAGE_RESOURCE_ID, dataList.get(possition)
                        .getImgResID());
            break;
      case 15:
            fragment = new FragmentOne();
            args.putString(FragmentOne.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentOne.IMAGE_RESOURCE_ID, dataList.get(possition)
                        .getImgResID());
            break;
      case 16:
            fragment = new FragmentTwo();
            args.putString(FragmentTwo.ITEM_NAME, dataList.get(possition)
                        .getItemName());
            args.putInt(FragmentTwo.IMAGE_RESOURCE_ID, dataList.get(possition)
                        .getImgResID());
            break;
      default:
            break;
      }
 
      fragment.setArguments(args);
      FragmentManager frgManager = getFragmentManager();
      frgManager.beginTransaction().replace(R.id.content_frame, fragment)
                  .commit();
 
      mDrawerList.setItemChecked(possition, true);
      setTitle(dataList.get(possition).getItemName());
      mDrawerLayout.closeDrawer(mDrawerList);
 
}

Now update the OnItemClickListener to select the correct fragment when selecting the  drawer item.

Updates for DrawerItemClickListener class in MainActivity
1
2
3
4
5
6
7
8
9
10
11
12
...
                private class DrawerItemClickListener implements
                  ListView.OnItemClickListener {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                        long id) {
                  if (dataList.get(position).getTitle() == null) {
                        SelectItem(position);
                  }
 
            }
      }

Now our customized drawer is completed. You can run this application in a emulator or in a real android device to see it in action. This is only one way which I found to do the customization in a navigation drawer. This may not be the most convenient way to customize the navigation drawer but we can add any other views like check box, buttons and other compatible views to the drawer using this method. Below you can download the source code for basic navigation drawer and custom navigation drawer. See the video demonstration below I’ll explain how to do this tutorial beginning to end.

If you have any issues regarding this tutorial feel free to ask. You can use comment section to communicate with me. If you like this tutorial share this with others. Subscribe our GooglePlus,Youtube and Facebook page to get instant notification about our new tutorials and videos. Or subscribe to your website using your email address to get instant email notification. Thank you very much for visiting my website.

Video Demonstration


반응형

'차근차근 > Android' 카테고리의 다른 글

Navigation Drawer 분석  (0) 2015.02.04
actionbar , Navigation Drawer, overlay  (0) 2015.02.04
actionbar 란  (0) 2015.02.03
actionbar submenu  (0) 2015.02.03
actionbar , 하단tab  (0) 2015.02.03