In this post, I’ll show you how to implement it with Material Design style. All the steps are quite similar to the pre-Lollipop version, but I still go through every single steps to help you feel easier.
Before started, you can watch the demo for this post to have an overview about what we will achieve:
Let’s get start it!
1 – Include Appcompat v21 in your graddle file Add following dependencies to Graddle build file to be able to use Material Design style in your app:
dependencies {
compile ' com . android . support : appcompat - v7: 21.0 .+ '
}
2 – Create Toobar
Firstly, you need to create toolbar.xml layout. This will contain the new style toolbar only and can be reused through your application:
<? xml version = "1.0" encoding = "utf-8" ?>
< android . support . v7 . widget . Toolbar xmlns: android = "http://schemas.android.com/apk/res/android"
xmlns: app = "http://schemas.android.com/apk/res-auto"
android: layout_width = "match_parent"
android: layout_height = "wrap_content"
android: background = "?attr/colorPrimary"
android: minHeight = "?attr/actionBarSize"
app: theme = "@style/AppTheme"
app: popupTheme = "@style/Theme.AppCompat.Light" />
Â
Then, you can include it in any activity. Here I embed it into the main_activity.xml :
< LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
xmlns: tools = "http://schemas.android.com/tools"
android: layout_width = "match_parent"
android: layout_height = "match_parent"
android: orientation = "vertical"
tools: context = ".MainActivity" >
< include
android: id = "@+id/toolbar"
layout = "@layout/toolbar" />
</ LinearLayout >
Â
3 – Drawer Menu Next, move to the Drawer Navigation part. As you know, the Drawer Navigation has 2 essential parts are the sliding menu and the frame container. And these 2 parts need to be placed inside the DrawerLayout . Like this:
< LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
xmlns: tools = "http://schemas.android.com/tools"
android: layout_width = "match_parent"
android: layout_height = "match_parent"
android: orientation = "vertical"
tools: context = ".MainActivity" >
< include
android: id = "@+id/toolbar"
layout = "@layout/toolbar" />
< android . support . v4 . widget . DrawerLayout
android: id = "@+id/drawer_layout"
android: layout_width = "match_parent"
android: layout_height = "match_parent" >
<!-- The main content view -->
< FrameLayout
android: id = "@+id/frame_container"
android: layout_width = "match_parent"
android: layout_height = "match_parent" />
<!-- The navigation drawer ( sliding menu ) -->
< ListView
android: id = "@+id/lv_drawer_menu"
android: layout_width = "240dp"
android: layout_height = "match_parent"
android: layout_gravity = "start"
android: choiceMode = "singleChoice"
android: background = "#fff"
android: divider = "@null"
android: dividerHeight = "0dp" />
</ android . support . v4 . widget . DrawerLayout >
</ LinearLayout >
Like you can see in the layout above, we are using ListView to display all items of Drawer Navigation menu. To layout and position all components in each menu item, we also need to create layout for them:
<? 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: padding = "@dimen/activity_horizontal_margin"
android: orientation = "horizontal" >
< ImageView
android: id = "@+id/img_drawer_menu_item_icon"
android: layout_width = "24dp"
android: layout_height = "24dp"
android: layout_gravity = "center_vertical" />
< TextView
android: id = "@+id/tv_drawer_menu_item_text"
android: layout_width = "fill_parent"
android: layout_height = "wrap_content"
android: layout_marginLeft = "@dimen/activity_horizontal_margin"
android: textColor = "#000"
android: layout_gravity = "center_vertical" />
</ LinearLayout >
After created the layout for Drawer Menu, we also need to create the DrawerMenuItem entity and DrawerMenuAdapter that used to manipulate data into Drawer Menu:
DrawerMenuItem.java
public class DrawerMenuItem {
private String mText ;
private int mIcon ;
public String getText () {
return mText ;
}
public void setText ( String mText ) {
this . mText = mText ;
}
public int getIcon () {
return mIcon ;
}
public void setIcon ( int mIcon ) {
this . mIcon = mIcon ;
}
}
DrawerMenuAdapter.java
public class DrawerMenuItemAdapter extends BaseAdapter {
List < DrawerMenuItem > mItems ;
Context mContext ;
public DrawerMenuItemAdapter ( Context context , List < DrawerMenuItem > mItems ) {
this . mItems = mItems ;
this . mContext = context ;
}
@Override
public int getCount () {
return mItems . size ();
}
@Override
public Object getItem ( int position ) {
return mItems . get ( position );
}
@Override
public long getItemId ( int position ) {
return position ;
}
@Override
public View getView ( int position , View convertView , ViewGroup parent ) {
if ( convertView == null ) {
LayoutInflater mInflater = ( LayoutInflater )
mContext . getSystemService ( Activity . LAYOUT_INFLATER_SERVICE );
convertView = mInflater . inflate ( R . layout . layout_drawer_menu_item , null );
}
ImageView imgIcon = ( ImageView ) convertView . findViewById ( R . id . img_drawer_menu_item_icon );
TextView tvTitle = ( TextView ) convertView . findViewById ( R . id . tv_drawer_menu_item_text );
DrawerMenuItem item = mItems . get ( position );
imgIcon . setImageResource ( item . getIcon ());
tvTitle . setText ( item . getText ());
return convertView ;
}
}
If you reached here and still don’t know what is the responsibility of entity and adapter class or how to implement ListView in Android, you should read this post to have a clear idea.
4 – Drawer Navigation Implementation Get back to MainActivity , firstly you have to declare all need variables:
private Toolbar mToolbar ;
private DrawerLayout mDrawerLayout ;
private ActionBarDrawerToggle mDrawerToggle ;
private ListView mLvDrawerMenu ;
private DrawerMenuItemAdapter mDrawerMenuAdapter ;
Then, in onCreate method, retrieve them from the layout or create new instance if needed. In other words, you do on initialization here:
mToolbar = ( Toolbar ) findViewById ( R . id . toolbar );
mDrawerLayout = ( DrawerLayout ) findViewById ( R . id . drawer_layout );
mLvDrawerMenu = ( ListView ) findViewById ( R . id . lv_drawer_menu );
List < DrawerMenuItem > menuItems = generateDrawerMenuItems ();
mDrawerMenuAdapter = new DrawerMenuItemAdapter ( getApplicationContext (), menuItems );
mLvDrawerMenu . setAdapter ( mDrawerMenuAdapter );
mLvDrawerMenu . setOnItemClickListener ( this );
mDrawerToggle = new ActionBarDrawerToggle ( this , mDrawerLayout , mToolbar , R . string . app_name , R . string . app_name ) {
public void onDrawerClosed ( View view ) {
invalidateOptionsMenu ();
}
public void onDrawerOpened ( View drawerView ) {
invalidateOptionsMenu ();
}
};
mDrawerLayout . setDrawerListener ( mDrawerToggle );
if ( savedInstanceState == null ){
setFragment ( 0 , BikeFragment . class );
}
The generateDrawerMenuItems() Â methods used to create a list of Drawer Menu items:
private List < DrawerMenuItem > generateDrawerMenuItems () {
String [] itemsText = getResources (). getStringArray ( R . array . nav_drawer_items );
TypedArray itemsIcon = getResources (). obtainTypedArray ( R . array . nav_drawer_icons );
List < DrawerMenuItem > result = new ArrayList < DrawerMenuItem >();
for ( int i = 0 ; i < itemsText . length ; i ++) {
DrawerMenuItem item = new DrawerMenuItem ();
item . setText ( itemsText [ i ]);
item . setIcon ( itemsIcon . getResourceId ( i , - 1 ));
result . add ( item );
}
return result ;
}
Implement the AdapterView.OnItemClickListener interface to handle click event for Drawer Menu items:
public class MainActivity extends ActionBarActivity implements AdapterView . OnItemClickListener {
…
@Override
public void onItemClick ( AdapterView <?> parent , View view , int position , long id ) {
switch ( position ){
case 0 :
setFragment ( 0 , BikeFragment . class );
break ;
case 1 :
setFragment ( 1 , BusFragment . class );
break ;
case 2 :
setFragment ( 2 , CarFragment . class );
break ;
case 3 :
mDrawerLayout . closeDrawer ( mLvDrawerMenu );
mLvDrawerMenu . invalidateViews ();
break ;
case 4 :
mDrawerLayout . closeDrawer ( mLvDrawerMenu );
mLvDrawerMenu . invalidateViews ();
break ;
case 5 :
mDrawerLayout . closeDrawer ( mLvDrawerMenu );
mLvDrawerMenu . invalidateViews ();
break ;
}
}
…
}
One more important methods that you need to implement is setFragment(), this methods use the set the proper Fragment to container when user select any Drawer Menu item:
public void setFragment ( int position , Class <? extends Fragment > fragmentClass ) {
try {
Fragment fragment = fragmentClass . newInstance ();
android . support . v4 . app . FragmentManager fragmentManager = getSupportFragmentManager ();
FragmentTransaction fragmentTransaction = fragmentManager . beginTransaction ();
fragmentTransaction . replace ( R . id . frame_container , fragment , fragmentClass . getSimpleName ());
fragmentTransaction . commit ();
mLvDrawerMenu . setItemChecked ( position , true );
mDrawerLayout . closeDrawer ( mLvDrawerMenu );
mLvDrawerMenu . invalidateViews ();
}
catch ( Exception ex ){
Log . e ( "setFragment" , ex . getMessage ());
}
}
Last but not least, override all needed methods to make sure that the Drawer Menu will work properly:
@Override
public void onBackPressed () {
if ( mDrawerLayout . isDrawerOpen ( mLvDrawerMenu )) {
mDrawerLayout . closeDrawer ( mLvDrawerMenu );
} else {
super . onBackPressed ();
}
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
@Override
protected void onPostCreate ( Bundle savedInstanceState ) {
super . onPostCreate ( savedInstanceState );
mDrawerToggle . syncState ();
}
@Override
public void onConfigurationChanged ( Configuration newConfig ) {
super . onConfigurationChanged ( newConfig );
// Pass any configuration change to the drawer toggls
mDrawerToggle . onConfigurationChanged ( newConfig );
}
The whole MainActivity.java content:
public class MainActivity extends ActionBarActivity implements AdapterView . OnItemClickListener {
private Toolbar mToolbar ;
private DrawerLayout mDrawerLayout ;
private ActionBarDrawerToggle mDrawerToggle ;
private ListView mLvDrawerMenu ;
private DrawerMenuItemAdapter mDrawerMenuAdapter ;
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView ( R . layout . activity_main );
mToolbar = ( Toolbar ) findViewById ( R . id . toolbar );
mDrawerLayout = ( DrawerLayout ) findViewById ( R . id . drawer_layout );
mLvDrawerMenu = ( ListView ) findViewById ( R . id . lv_drawer_menu );
List < DrawerMenuItem > menuItems = generateDrawerMenuItems ();
mDrawerMenuAdapter = new DrawerMenuItemAdapter ( getApplicationContext (), menuItems );
mLvDrawerMenu . setAdapter ( mDrawerMenuAdapter );
mLvDrawerMenu . setOnItemClickListener ( this );
mDrawerToggle = new ActionBarDrawerToggle ( this , mDrawerLayout , mToolbar , R . string . app_name , R . string . app_name ) {
public void onDrawerClosed ( View view ) {
invalidateOptionsMenu ();
}
public void onDrawerOpened ( View drawerView ) {
invalidateOptionsMenu ();
}
};
mDrawerLayout . setDrawerListener ( mDrawerToggle );
if ( savedInstanceState == null ){
setFragment ( 0 , BikeFragment . class );
}
}
@Override
public void onItemClick ( AdapterView <?> parent , View view , int position , long id ) {
switch ( position ){
case 0 :
setFragment ( 0 , BikeFragment . class );
break ;
case 1 :
setFragment ( 1 , BusFragment . class );
break ;
case 2 :
setFragment ( 2 , CarFragment . class );
break ;
case 3 :
mDrawerLayout . closeDrawer ( mLvDrawerMenu );
mLvDrawerMenu . invalidateViews ();
break ;
case 4 :
mDrawerLayout . closeDrawer ( mLvDrawerMenu );
mLvDrawerMenu . invalidateViews ();
break ;
case 5 :
mDrawerLayout . closeDrawer ( mLvDrawerMenu );
mLvDrawerMenu . invalidateViews ();
break ;
}
}
@Override
public void onBackPressed () {
if ( mDrawerLayout . isDrawerOpen ( mLvDrawerMenu )) {
mDrawerLayout . closeDrawer ( mLvDrawerMenu );
} else {
super . onBackPressed ();
}
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
@Override
protected void onPostCreate ( Bundle savedInstanceState ) {
super . onPostCreate ( savedInstanceState );
mDrawerToggle . syncState ();
}
@Override
public void onConfigurationChanged ( Configuration newConfig ) {
super . onConfigurationChanged ( newConfig );
// Pass any configuration change to the drawer toggls
mDrawerToggle . onConfigurationChanged ( newConfig );
}
public void setFragment ( int position , Class <? extends Fragment > fragmentClass ) {
try {
Fragment fragment = fragmentClass . newInstance ();
android . support . v4 . app . FragmentManager fragmentManager = getSupportFragmentManager ();
FragmentTransaction fragmentTransaction = fragmentManager . beginTransaction ();
fragmentTransaction . replace ( R . id . frame_container , fragment , fragmentClass . getSimpleName ());
fragmentTransaction . commit ();
mLvDrawerMenu . setItemChecked ( position , true );
mDrawerLayout . closeDrawer ( mLvDrawerMenu );
mLvDrawerMenu . invalidateViews ();
}
catch ( Exception ex ){
Log . e ( "setFragment" , ex . getMessage ());
}
}
private List < DrawerMenuItem > generateDrawerMenuItems () {
String [] itemsText = getResources (). getStringArray ( R . array . nav_drawer_items );
TypedArray itemsIcon = getResources (). obtainTypedArray ( R . array . nav_drawer_icons );
List < DrawerMenuItem > result = new ArrayList < DrawerMenuItem >();
for ( int i = 0 ; i < itemsText . length ; i ++) {
DrawerMenuItem item = new DrawerMenuItem ();
item . setText ( itemsText [ i ]);
item . setIcon ( itemsIcon . getResourceId ( i , - 1 ));
result . add ( item );
}
return result ;
}
}
Â
About BikeFragment , CarFragment , BusFragment , they are just dummy fragment with only one TextView to specify Fragment name.
Run the demo and enjoy Drawer Navigation Menu with Material Design style:
Â
5 - Download Source Code Drawer Navigation Menu with Material Design Style http://www.mediafire.com/download/4lariz1mt7w5j5y/DemoMaterialDesignDrawerMenu.zip
https://github.com/trinhlbk1991/DemoDrawerMenuMaterialDesign
This post is licensed under
CC BY 4.0 by the author.