Note: The code is working but we are currently improving this article.
This is a step by step guide on how to create a navigation drawer for your Android app.
This is a step by step guide on how to create a navigation drawer for your Android app.
DOWNLOAD SOURCE CODE
First, create a new project File > New > Android Application Project > "NavigationDrawerExample"
Steps:
1. Change activity_main.xml to navigation drawer layout
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" > <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" /> <ListView android:id="@+id/left_drawer" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:background="#111" android:choiceMode="singleChoice" android:divider="@android:color/transparent" android:dividerHeight="0dp" /> </android.support.v4.widget.DrawerLayout>
2. Prepare MainActivity properties
private String[] mNavigationDrawerItemTitles; private DrawerLayout mDrawerLayout; private ListView mDrawerList;
3. res/values/strings.xml - put the drawer items array
<string-array name="navigation_drawer_items_array"> <item>Create</item> <item>Read</item> <item>Help</item> </string-array>
4. put inside MainActivity.java oncreate - initialize three properties
mNavigationDrawerItemTitles= getResources().getStringArray(R.array.navigation_drawer_items_array); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList = (ListView) findViewById(R.id.left_drawer);
5. create res/layouts/listview_item_row.xml
This is for list view inside navigation drawer. Right click res/layouts/ folder > New > File > Name it "listview_item_row.xml"<RelativeLayout xmlns:android="http://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="Folder name here." android:textAppearance="?android:attr/textAppearanceListItemSmall" android:textColor="#ffffff" /> </RelativeLayout>
6. create an object for drawer item ObjectDrawerItem.java
File > New > Class > Name it "ObjectDrawerItem"
public class ObjectDrawerItem { public int icon; public String name; // Constructor. public ObjectDrawerItem(int icon, String name) { this.icon = icon; this.name = name; } }
7. put nav drawer item icons in res/drawable-hdpi/
I have:
ic_action_copy.png
ic_action_refresh.png
ic_action_share.png
8. put inside oncreate - list the drawer items
ObjectDrawerItem[] drawerItem = new ObjectDrawerItem[3]; drawerItem[0] = new ObjectDrawerItem(R.drawable.ic_action_copy, "Create"); drawerItem[1] = new ObjectDrawerItem(R.drawable.ic_action_refresh, "Read"); drawerItem[2] = new ObjectDrawerItem(R.drawable.ic_action_share, "Help");
9. create the custom adapter DrawerItemCustomAdapter.java
public class DrawerItemCustomAdapter extends ArrayAdapter<ObjectDrawerItem> { Context mContext; int layoutResourceId; ObjectDrawerItem data[] = null; public DrawerItemCustomAdapter(Context mContext, int layoutResourceId, ObjectDrawerItem[] 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); ObjectDrawerItem folder = data[position]; imageViewIcon.setImageResource(folder.icon); textViewName.setText(folder.name); return listItem; } }
10. pass the list of drawer items to DrawerItemCustomAdapter
This is to create the adapter - inside MainActivity.java oncreate
DrawerItemCustomAdapter adapter = new DrawerItemCustomAdapter(this, R.layout.listview_item_row, drawerItem);
11. set the adapter - oncreate
mDrawerList.setAdapter(adapter);
12. create the item click listener DrawerItemClickListener.java
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 CreateFragment(); break; case 1: fragment = new ReadFragment(); break; case 2: fragment = new HelpFragment(); break; default: break; } if (fragment != null) { FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit(); mDrawerList.setItemChecked(position, true); mDrawerList.setSelection(position); getActionBar().setTitle(mNavigationDrawerItemTitles[position]); mDrawerLayout.closeDrawer(mDrawerList); } else { Log.e("MainActivity", "Error in creating fragment"); } }
13. create the needed fragments and the views to inflate in res/layout/
(i.e. CreateFragment.java => res/layout/fragment_create.xml)
CreateFragment.java
public class CreateFragment extends Fragment { public CreateFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_create, container, false); return rootView; } }
fragment_create.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/txtLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Create View" android:textSize="16dp" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/txtLabel" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:src="@drawable/ic_action_copy" /> </RelativeLayout>
14. set the item click listener - oncreate
...and Inside MainActivity.java
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
15. try to run - swipe your finger left to right - it works!
As of this stage, the app icon is useless to the nav drawer. It cannot trigger the nav drawer. This is what will be our next steps.
16. for app icon control for nav drawer, add new property on MainActivity
ActionBarDrawerToggle mDrawerToggle;
17. add ic_drawer.png in res/drawable-hdpi/
18. add open and close description in values/string/
<string name="drawer_open">Open navigation drawer</string> <string name="drawer_close">Close navigation drawer</string>
19. Set properties for proper title display
private CharSequence mDrawerTitle; private CharSequence mTitle;
..and inside onCreate, after setContentView
mTitle = mDrawerTitle = getTitle();
20. add the app icon control code inside MainActivity oncreate
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerToggle = new ActionBarDrawerToggle( this, mDrawerLayout, R.drawable.ic_drawer, 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); getActionBar().setTitle(mTitle); } /** Called when a drawer has settled in a completely open state. */ public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); getActionBar().setTitle(mDrawerTitle); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true);
21. add onOptionsItemSelected() method
really needed to make app icon a toggle of nav drawer
@Override public boolean onOptionsItemSelected(MenuItem item) { if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); }
22. Override setTitle() method
really needed for changing titles
@Override public void setTitle(CharSequence title) { mTitle = title; getActionBar().setTitle(mTitle); }
and then change this line
getActionBar().setTitle(mNavigationDrawerItemTitles[position]);
to this line
setTitle(mNavigationDrawerItemTitles[position]);
23. onPostCreate() method
really needed to change the up caret icon before the app icon
@Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); mDrawerToggle.syncState(); }
Lower Android (2.2+) Version Compatibility
Android Navigation Drawer only works for Honeycomb and Up. To make it work with pre-honeycome devices, you should use the Android support library. Download it first using your SDK manager and then follow the step by step guide here.
More about the Navigation Drawer:
http://stackoverflow.com/q/17388574
https://developer.android.com/design/patterns/navigation-drawer.html
The Code of a Ninja Resources
For FREE programming tutorials, click the red button below and subscribe! :)
website