Yes that’s true. But there are still shortage of community which provide resources and relavent information about this Material Drawer Library.
In this blog We are going to implement this library in our project. And later we will see how we can tailor the flow as per our application requirement.
Demo
You can download the complete sample application from here.
Setup
1. Provide the gradle dependency
1 2 3 |
compile('com.mikepenz:materialdrawer:5.2.0@aar') { transitive = true } |
note: add transitive dependencies by setting transitive = true for the material drawer dependency. This will add all the relevant dependency required by the material drawer library.
Also there are some other dependency that we can add to speed up the implementation:
1 2 3 4 5 |
compile 'com.mikepenz:google-material-typeface:2.2.0.1@aar' compile 'com.mikepenz:fontawesome-typeface:4.4.0.1@aar' compile 'com.android.support:appcompat-v7:23.2.0' compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.mikepenz:itemanimators:0.2.4@aar' |
compile ‘com.mikepenz:google-material-typeface:2.2.0.1@aar’ , compile ‘com.mikepenz:fontawesome-typeface:4.4.0.1@aar’ are the GitHub libraries that maintain Google recommended material based icons. This will boost our development process without worrying about the icon required.
We have used Picasso as a image loading and caching library.
2. Initialize and create the image loader logic
1 2 3 4 5 6 7 8 9 10 11 12 13 |
DrawerImageLoader.init(new AbstractDrawerImageLoader() { @Override public void set(ImageView imageView, Uri uri, Drawable placeholder) { Picasso.with(imageView.getContext()).load(uri).placeholder(placeholder).into(imageView); } @Override public void cancel(ImageView imageView) { Picasso.with(imageView.getContext()).cancelRequest(imageView); } }); |
Note: Image loading is done in picasso but it can be change to any library.
3. Create a few sample profile
1 2 3 4 5 6 7 8 |
// Create a few sample profile // NOTE you have to define the loader logic too. See the CustomApplication for more details final IProfile profile = new ProfileDrawerItem().withName("Mike Penz").withEmail("mikepenz@gmail.com").withIcon("https://avatars3.githubusercontent.com/u/1476232?v=3&s=460").withIdentifier(100); final IProfile profile2 = new ProfileDrawerItem().withName("Bernat Borras").withEmail("alorma@github.com").withIcon(Uri.parse("https://avatars3.githubusercontent.com/u/887462?v=3&s=460")).withIdentifier(101); final IProfile profile3 = new ProfileDrawerItem().withName("Max Muster").withEmail("max.mustermann@gmail.com").withIcon(R.drawable.profile2).withIdentifier(102); final IProfile profile4 = new ProfileDrawerItem().withName("Felix House").withEmail("felix.house@gmail.com").withIcon(R.drawable.profile3).withIdentifier(103); final IProfile profile5 = new ProfileDrawerItem().withName("Mr. X").withEmail("mister.x.super@gmail.com").withIcon(R.drawable.profile4).withIdentifier(104); final IProfile profile6 = new ProfileDrawerItem().withName("Batman").withEmail("batman@gmail.com").withIcon(R.drawable.profile5).withIdentifier(105); |
Note: IProfile is the interface that can be used to display multiple type of profiles based on the requirement.
Here we have passed the ProfileDrawerItem object which is used to display the profile as a drawer item of the Drawer.
We can set the icon from URL ,Drawable , DrawableRes or Bitmap.
Here Identifier is used to identifying a particular element. This is usually used OnDrawerItemClickListener to identify which drawer item has been clicked.
4. Create the AccountHeader
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 |
// Create the AccountHeader headerResult = new AccountHeaderBuilder() .withActivity(this) .withTranslucentStatusBar(true) .withHeaderBackground(R.drawable.header) .addProfiles( // Adding profiles to header view profile, profile2, profile3, profile4, profile5, profile6, //don't ask but google uses 14dp for the add account icon in gmail but 20dp for the normal icons (like manage account) // Adding setting drawer item other than profile drawer item new ProfileSettingDrawerItem().withName("Add Account").withDescription("Add new GitHub Account").withIcon(new IconicsDrawable(this, GoogleMaterial.Icon.gmd_plus).actionBar().paddingDp(5).colorRes(R.color.material_drawer_primary_text)).withIdentifier(PROFILE_SETTING), new ProfileSettingDrawerItem().withName("Manage Account").withIcon(GoogleMaterial.Icon.gmd_settings).withIdentifier(100001) ) .withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() { @Override public boolean onProfileChanged(View view, IProfile profile, boolean current) { //sample usage of the onProfileChanged listener //if the clicked item has the identifier 1 add a new profile ;) if (profile instanceof IDrawerItem && profile.getIdentifier() == PROFILE_SETTING) { int count = 100 + headerResult.getProfiles().size() + 1; IProfile newProfile = new ProfileDrawerItem().withNameShown(true).withName("Batman" + count).withEmail("batman" + count + "@gmail.com").withIcon(R.drawable.profile5).withIdentifier(count); if (headerResult.getProfiles() != null) { //we know that there are 2 setting elements. set the new profile above them ;) headerResult.addProfile(newProfile, headerResult.getProfiles().size() - 2); } else { headerResult.addProfiles(newProfile); } } //false if you have not consumed the event and it should close the drawer return false; } }) .withSavedInstance(savedInstanceState) .build(); |
Note: AccountHeaderBuilder class allow up to create a header of the drawer. We can create our custom header or use among the available header files.
You can change the header by using withAccountHeader(R.layout.myHeaderView). Also to set compact header layout use withCompactStyle(true).
Here withOnAccountHeaderListener all the profile changed events related to AccountHeader are managed.
5. Create the drawer
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 |
//Create the drawer result = new DrawerBuilder() .withActivity(this) .withToolbar(toolbar) .withHasStableIds(true) .withItemAnimator(new AlphaCrossFadeAnimator()) .withAccountHeader(headerResult) //set the AccountHeader we created earlier for the header .addDrawerItems( new PrimaryDrawerItem().withName(R.string.drawer_item_compact_header).withDescription(R.string.drawer_item_compact_header_desc).withIcon(GoogleMaterial.Icon.gmd_sun).withIdentifier(1).withSelectable(false), new PrimaryDrawerItem().withName(R.string.drawer_item_action_bar_drawer).withDescription(R.string.drawer_item_action_bar_drawer_desc).withIcon(FontAwesome.Icon.faw_home).withIdentifier(2).withSelectable(false), new PrimaryDrawerItem().withName(R.string.drawer_item_multi_drawer).withDescription(R.string.drawer_item_multi_drawer_desc).withIcon(FontAwesome.Icon.faw_gamepad).withIdentifier(3).withSelectable(false), new PrimaryDrawerItem().withName(R.string.drawer_item_non_translucent_status_drawer).withDescription(R.string.drawer_item_non_translucent_status_drawer_desc).withIcon(FontAwesome.Icon.faw_eye).withIdentifier(4).withSelectable(false).withBadgeStyle(new BadgeStyle().withTextColor(Color.WHITE).withColorRes(R.color.md_red_700)), new PrimaryDrawerItem().withName(R.string.drawer_item_advanced_drawer).withDescription(R.string.drawer_item_advanced_drawer_desc).withIcon(GoogleMaterial.Icon.gmd_adb).withIdentifier(5).withSelectable(false), new PrimaryDrawerItem().withName(R.string.drawer_item_embedded_drawer).withDescription(R.string.drawer_item_embedded_drawer_desc).withIcon(GoogleMaterial.Icon.gmd_battery).withIdentifier(7).withSelectable(false), new PrimaryDrawerItem().withName(R.string.drawer_item_fullscreen_drawer).withDescription(R.string.drawer_item_fullscreen_drawer_desc).withIcon(GoogleMaterial.Icon.gmd_labels).withIdentifier(8).withSelectable(false), new PrimaryDrawerItem().withName(R.string.drawer_item_custom_container_drawer).withDescription(R.string.drawer_item_custom_container_drawer_desc).withIcon(GoogleMaterial.Icon.gmd_my_location).withIdentifier(9).withSelectable(false), new PrimaryDrawerItem().withName(R.string.drawer_item_menu_drawer).withDescription(R.string.drawer_item_menu_drawer_desc).withIcon(GoogleMaterial.Icon.gmd_filter_list).withIdentifier(10).withSelectable(false), new PrimaryDrawerItem().withName(R.string.drawer_item_mini_drawer).withDescription(R.string.drawer_item_mini_drawer_desc).withIcon(GoogleMaterial.Icon.gmd_battery_charging).withIdentifier(11).withSelectable(false), new PrimaryDrawerItem().withName(R.string.drawer_item_fragment_drawer).withDescription(R.string.drawer_item_fragment_drawer_desc).withIcon(GoogleMaterial.Icon.gmd_disc_full).withIdentifier(12).withSelectable(false), new PrimaryDrawerItem().withName(R.string.drawer_item_collapsing_toolbar_drawer).withDescription(R.string.drawer_item_collapsing_toolbar_drawer_desc).withIcon(GoogleMaterial.Icon.gmd_camera_rear).withIdentifier(13).withSelectable(false), new PrimaryDrawerItem().withName(R.string.drawer_item_persistent_compact_header).withDescription(R.string.drawer_item_persistent_compact_header_desc).withIcon(GoogleMaterial.Icon.gmd_brightness_5).withIdentifier(14).withSelectable(false), new PrimaryDrawerItem().withName(R.string.drawer_item_crossfade_drawer_layout_drawer).withDescription(R.string.drawer_item_crossfade_drawer_layout_drawer_desc).withIcon(GoogleMaterial.Icon.gmd_format_bold).withIdentifier(15).withSelectable(false), new SectionDrawerItem().withName(R.string.drawer_item_section_header), new ExpandableDrawerItem().withName("Collapsable").withIcon(GoogleMaterial.Icon.gmd_collection_case_play).withIdentifier(19).withSelectable(false).withSubItems( new SecondaryDrawerItem().withName("CollapsableItem").withLevel(2).withIcon(GoogleMaterial.Icon.gmd_8tracks).withIdentifier(2000), new SecondaryDrawerItem().withName("CollapsableItem 2").withLevel(2).withIcon(GoogleMaterial.Icon.gmd_8tracks).withIdentifier(2001) ), new SecondaryDrawerItem().withName(R.string.drawer_item_open_source).withIcon(FontAwesome.Icon.faw_github).withIdentifier(20).withSelectable(false), new SecondaryDrawerItem().withName(R.string.drawer_item_contact).withIcon(GoogleMaterial.Icon.gmd_format_color_fill).withIdentifier(21).withTag("Bullhorn"), new DividerDrawerItem(), new SwitchDrawerItem().withName("Switch").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(onCheckedChangeListener), new SwitchDrawerItem().withName("Switch2").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(onCheckedChangeListener).withSelectable(false), new ToggleDrawerItem().withName("Toggle").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(onCheckedChangeListener), new DividerDrawerItem(), new SecondarySwitchDrawerItem().withName("Secondary switch").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(onCheckedChangeListener), new SecondarySwitchDrawerItem().withName("Secondary Switch2").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(onCheckedChangeListener).withSelectable(false), new SecondaryToggleDrawerItem().withName("Secondary toggle").withIcon(Octicons.Icon.oct_tools).withChecked(true).withOnCheckedChangeListener(onCheckedChangeListener) ) // add the items we want to use with our Drawer .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { @Override public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { //check if the drawerItem is set. //there are different reasons for the drawerItem to be null //--> click on the header //--> click on the footer //those items don't contain a drawerItem if (drawerItem != null) { Intent intent = null; if (drawerItem.getIdentifier() == 1) { intent = new Intent(DrawerActivity.this, CompactHeaderDrawerActivity.class); } else if (drawerItem.getIdentifier() == 2) { intent = new Intent(DrawerActivity.this, ActionBarActivity.class); } else if (drawerItem.getIdentifier() == 3) { intent = new Intent(DrawerActivity.this, MultiDrawerActivity.class); } else if (drawerItem.getIdentifier() == 4) { intent = new Intent(DrawerActivity.this, NonTranslucentDrawerActivity.class); } else if (drawerItem.getIdentifier() == 5) { intent = new Intent(DrawerActivity.this, AdvancedActivity.class); } else if (drawerItem.getIdentifier() == 7) { intent = new Intent(DrawerActivity.this, EmbeddedDrawerActivity.class); } else if (drawerItem.getIdentifier() == 8) { intent = new Intent(DrawerActivity.this, FullscreenDrawerActivity.class); } else if (drawerItem.getIdentifier() == 9) { intent = new Intent(DrawerActivity.this, CustomContainerActivity.class); } else if (drawerItem.getIdentifier() == 10) { intent = new Intent(DrawerActivity.this, MenuDrawerActivity.class); } else if (drawerItem.getIdentifier() == 11) { intent = new Intent(DrawerActivity.this, MiniDrawerActivity.class); } else if (drawerItem.getIdentifier() == 12) { intent = new Intent(DrawerActivity.this, FragmentActivity.class); } else if (drawerItem.getIdentifier() == 13) { intent = new Intent(DrawerActivity.this, CollapsingToolbarActivity.class); } else if (drawerItem.getIdentifier() == 14) { intent = new Intent(DrawerActivity.this, PersistentDrawerActivity.class); } else if (drawerItem.getIdentifier() == 15) { intent = new Intent(DrawerActivity.this, CrossfadeDrawerLayoutActvitiy.class); } else if (drawerItem.getIdentifier() == 20) { intent = new LibsBuilder() .withFields(R.string.class.getFields()) .withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR) .intent(DrawerActivity.this); } if (intent != null) { DrawerActivity.this.startActivity(intent); } } return false; } }) .withSavedInstance(savedInstanceState) .withShowDrawerOnFirstLaunch(true) .build(); //if you have many different types of DrawerItems you can magically pre-cache those items to get a better scroll performance //make sure to init the cache after the DrawerBuilder was created as this will first clear the cache to make sure no old elements are in //RecyclerViewCacheUtil.getInstance().withCacheSize(2).init(result); new RecyclerViewCacheUtil<IDrawerItem>().withCacheSize(2).apply(result.getRecyclerView(), result.getDrawerItems()); //only set the active selection or active profile if we do not recreate the activity if (savedInstanceState == null) { // set the selection to the item with the identifier 11 result.setSelection(21, false); //set the active profile headerResult.setActiveProfile(profile3); } result.updateBadge(4, new StringHolder(10 + "")); |
Note: Here we have added multiple type of drawer items namely PrimaryDrawerItem, SectionDrawerItem, ExpandableDrawerItem and like that. Check the main drawer for all types of Drawer items provideded by the Material Drawer library
Here withOnDrawerItemClickListener handles all the drawer items click events related to Drawer.
Also, .withAccountHeader(headerResult) automatically sets the AccountHeader that we created earlier for the header.
That’s all folks. Stay updated.
Important Links: