Creating a Navigation Drawer
In the latest I/O 2013, Google added a new pattern: Drawer Navigation.
I think Google did really good job.
You can find official design guidelines here.
Implementing drawer navigation is simple. The components required are now included in the latest support library (release 13).
The first thing that we need to do is modify our layout and insert a DrawerLayout.
It is enough to get a empty Navigation Drawer working.
If we swipe from the left hand edge of the screen our Navigation Drawer appears.
Now we can populate our List with a simple Adapter.
To handle click on menu item:
To handle the app icon touch event you can use:
When the user expands the navigation drawer, you should remove actions from the action bar that are contextual to the underlying view.
You can use our ActionBarDrawerToggle:
Finally if we want add a shadow:
You can get code from GitHub:
I think Google did really good job.
You can find official design guidelines here.
Implementing drawer navigation is simple. The components required are now included in the latest support library (release 13).
The first thing that we need to do is modify our layout and insert a DrawerLayout.
It is important to note:
- The main content view (the RelativeLayout above) must be the first child
- The width of the navigation drawer should be between a minimum of 240 dp and a maximum of 320 dp
- The height of the navigation drawer should be match_parent
- The drawer view (the ListView) must specify its horizontal gravity with the android:layout_gravity
It is enough to get a empty Navigation Drawer working.
If we swipe from the left hand edge of the screen our Navigation Drawer appears.
Now we can populate our List with a simple Adapter.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_drawer); _initMenu(); } private void _initMenu() { NsMenuAdapter mAdapter = new NsMenuAdapter(this); // Add Header mAdapter.addHeader(R.string.ns_menu_main_header); ..... mAdapter.addItem(mItem); mDrawerList = (ListView) findViewById(R.id.drawer); if (mDrawerList != null) mDrawerList.setAdapter(mAdapter); }With a very simple code, we have our drawer.
To handle click on menu item:
private void _initMenu() { ..... mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); } private class DrawerItemClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView parent, View view, int position,long id) { // Highlight the selected item, update the title, and close the drawer // update selected item and title, then close the drawer mDrawerList.setItemChecked(position, true); setTitle("......"); String text= "menu click... should be implemented"; Toast.makeText(MainActivity.this, text , Toast.LENGTH_LONG).show(); mDrawer.closeDrawer(mDrawerList); } }To listen for drawer open and close events, and use new drawer navigation icon, we should use the ActionBarDrawerToggle class:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_drawer); // enable ActionBar app icon to behave as action to toggle nav drawer getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true); mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerToggle = new CustomActionBarDrawerToggle(this, mDrawer); mDrawer.setDrawerListener(mDrawerToggle); } private class CustomActionBarDrawerToggle extends ActionBarDrawerToggle { public CustomActionBarDrawerToggle(Activity mActivity,DrawerLayout mDrawerLayout){ super( mActivity, /* host Activity */ mDrawerLayout, /* DrawerLayout object */ R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */ R.string.ns_menu_open, /* "open drawer" description */ R.string.ns_menu_close); /* "close drawer" description */ } /** Called when a drawer has settled in a completely closed state. */ @Override public void onDrawerClosed(View view) { getActionBar().setTitle(getString(R.string.ns_menu_close)); } /** Called when a drawer has settled in a completely open state. */ @Override public void onDrawerOpened(View drawerView) { getActionBar().setTitle(getString(R.string.ns_menu_open)); } }The drawer navigation implementation page provides a link to a zip file for the default drawer navigation icon in both light and dark holo theme.
To handle the app icon touch event you can use:
@Override public boolean onOptionsItemSelected(MenuItem item) { // Pass the event to ActionBarDrawerToggle, if it returns // true, then it has handled the app icon touch event if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } // Handle your other action bar items... return super.onOptionsItemSelected(item); }To work properly you have to insert also this code:
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); mDrawerToggle.onConfigurationChanged(newConfig); }It is very important, manage icons on action bar.
When the user expands the navigation drawer, you should remove actions from the action bar that are contextual to the underlying view.
You can use our ActionBarDrawerToggle:
private class CustomActionBarDrawerToggle extends ActionBarDrawerToggle { @Override public void onDrawerClosed(View view) { invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() } @Override public void onDrawerOpened(View drawerView) { invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() } } /* Called whenever we call invalidateOptionsMenu() */ @Override public boolean onPrepareOptionsMenu(Menu menu) { // If the nav drawer is open, hide action items related to the content view boolean drawerOpen = mDrawer.isDrawerOpen(mDrawerList); menu.findItem(R.id.action_save).setVisible(!drawerOpen); return super.onPrepareOptionsMenu(menu); }
Finally if we want add a shadow:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout); // set a custom shadow that overlays the main content when the drawer opens mDrawer.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); }
You can get code from GitHub:
Comments
Post a Comment