Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

Using the Navigation Drawer in Android

android navigation drawer

  • Please log in to reply
No replies to this topic

#1 farrell2k

farrell2k

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 169 posts

Posted 28 April 2014 - 12:23 PM

How to implement a simple Navigation Drawer in your android application.    The DrawerLayout class, which is the starting point of a Navigation Drawer is only available in the v4 support library, so make sure you have that downloaded.   The first step is to create a project with a minsdkversion of 9, Android 2.3  If you use eclipse like me, this is easy.  Just keep the name MainActivity for your activity and activity_main for its xml layout.     do yourself a favor and delete all the fragment nonsense so that it doesn't confuse you.
 
Now we need to create the layout for the navigation drawer.   If you were as confused as me about how this all works, you probably though that the drawer was a view that attaches itself to your main layout.   It is not.   The drawer itself is your entire layout.  You will see what I mean.  so we create our layout.    Open up activity_main and remove everything.   We have to add the drawer as our main layout.  My activity_main looks like this.
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.andro...pk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context="org.tjf.testapp.MainActivity"
    tools:ignore="MergeRootFrame" >
 
    <!-- FrameLayout contains the content we see in our activity when the drawer is closed.
    I am just going to display a text view,but you can stick a MapView or MapFragment here.
    A FrameLaout MUST be the first child in this
    DrawerLayout. -->
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
        <TextView
            android:id="@+id/tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Main Layout widgets or fragments added here..."/>
    </FrameLayout>
 
<!-- According to the docs, the listview MUST specity a layout_gravity -->
    <ListView
        android:id="@+id/drawer_list"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity="start" />
 
</android.support.v4.widget.DrawerLayout> 
So the FrameLayout can contain any number of other layouts, and is what you will see in your activity when the drawer is not covering it.   The drawer itself just contains a Listview that will house 3 options, "Settings", Help", and "About", which are populated from an array.  I hope you understand list views.  Let's do that now.     In strings.xml I have:
 <string-array name="nav_items">
        <item>Settings</item>
        <item>Help</item>
        <item>About</item>
    </string-array>
Now comes the confusing part, but it's easy if you just concentrate.   The first thing we need to do is get a reference to the DrawerLayout.   The second thing we need to do is implement an interface that monitors when the NavigationDrawer opens and closes.   DrawerLayout.DrawerListener is that interface with its ondrawerOpened() and onDrawerClosed().  You can use a Nav Drawer with or without the Action Bar, but 99% of the time you will see it used in conjunction with the Action Bar - i.e. you click the icon on the Bar at top left and the drawer pops out from the left of the screen.  Because of this, Google has graciously provided us with a concrete implementation of DrawerLayout.DrawerListener in the class ActionBarDrawerToggle. This class handles all of the interface methods, as well as integrating and displaying that little icon that shows in the action bar, the one made of 3 lines stacked on top of one another.   You must  download this here and add the images to your res/drawable folders:
 
So here is my commented MainActivity.  I'll attach the eclipse project here as well.
package org.tjf.testapp;
 
import android.content.res.Configuration;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
 
public class MainActivity extends ActionBarActivity {
//the items displayed in the navigation drawer.
private String[] navItems;
//the drawerlayout.  
private DrawerLayout drawerLayout;
//the concrete implementation of DrawerLayout.DrawerListener.
private ActionBarDrawerToggle drawerToggle;
//the listview that displays navItems.
private ListView drawerList;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
 
//we want to be able to navigate with the home icon (top left).
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        
//instantiate our items.
init();
}
 
// instantiate items.
private void init() {
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
//setScrimcolor.  Strange name.  Makes sure that the drawer doesn't fade to black.  Keeps it white.
drawerLayout.setScrimColor(Color.WHITE);
//The drawer shadown.  A 9 patch that adds a nice little hadow to the edge of the drawer. Uncomment it to see.
drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
//our concrete implementation of DrawerToggle.DrawerListener (copied from developer example.)
drawerToggle = new ActionBarDrawerToggle(
                this,                  /* host Activity */
                drawerLayout,         /* DrawerLayout object */
                R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
                R.string.drawer_open,  /* "open drawer" description for accessibility */
                R.string.drawer_close  /* "close drawer" description for accessibility */
                ) {
//when the drawer is closed, the action bar title reads "Closed"
            public void onDrawerClosed(View view) {
                getSupportActionBar().setTitle("Closed");
            }
            
          //when the drawer is closed, the action bar title reads "Open"
            public void onDrawerOpened(View drawerView) {
                getSupportActionBar().setTitle("Opened");
            }
        };
        
        //set the listener for the drawer
drawerLayout.setDrawerListener(drawerToggle);
//instantiate the navItems array.
navItems = getResources().getStringArray(R.array.nav_items);
//grab our listview.
drawerList = (ListView) findViewById(R.id.drawer_list);
//set the listview adapter.
drawerList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, navItems));
//set the click listener for our listview.
drawerList.setOnItemClickListener(new ListViewMonitor());
}
 
/*
* Helper class to handle callbacks for the listview clicks.
*/
private class ListViewMonitor implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, navItems[position], Toast.LENGTH_LONG).show();
}
}//end ListViewMonitor.
 
//The standard method for handling the menu key or overflow : on action bar.
@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;
}
 
 
@Override
public boolean onOptionsItemSelected(MenuItem item) {
/* when the home icon in the action bar is clicked, call up
* to drawerToggle.onOptionsItemSelected(item).  It just
* calls openDrawer() or closeDrawer() on the DrawerLayout to
* open and close it.
*/
if (drawerToggle.onOptionsItemSelected(item)) {
     return true;
   }
 
//standard menu stuff.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
 
/* The documentation says that this needs to be called here to sync
the state of the drawerlayout with the action bar when the your
activity is destroyed and ui is restored from onRestoreInstanceState().
*/
@Override
protected void onPostResume() {
super.onPostResume();
drawerToggle.syncState();
}
 
/* The documentation says this has to be impemented as well, but mine works
* fine without it.  Whatever...
*/
@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }
}

  • 1

Averageloser.com - I used to be a programmer like you, then I took a -> in the knee.