MaterialDrawer

Additional

Language
Kotlin
Version
v8.0.0-b01 (Feb 2, 2020)
Created
Jan 31, 2015
Updated
Feb 2, 2020
Owner
Mike Penz (mikepenz)
Contributors
Yoav Sternberg (yoavst)
Mike Penz (mikepenz)
Bernat Borrás Paronella (alorma)
talklittle
emartynov
androideveloper
Michal Tajchert (tajchert)
tilal6991
gitter-badger
Niklas Baudy (vanniktech)
davidcesarino
Michael Basil (intrications)
wKovacs64
FriesischScott
Fuhrmann
IgorGanapolsky
srodenberg
gpulido
Show all (94)94
Activity
Badge
Generate
Download
Source code
APK file

Commercial

MaterialDrawer

Does your application contain a Drawer? Do you want to have it up and running in less than 5 minutes? Do you want your drawer to follow the Android Design Guidelines? Do you have profiles? Do you need flexibility? Is Google's navigation Drawer of the design support not enough for you? Do you want a simple and easy to understand api?

If any (or all) of these questions seem familiar, the MaterialDrawer is the perfect library for you all.

Never waste your time again. It provides you with the easiest possible implementation of a navigation drawer for your application. There is a Header with profiles (AccountHeader), a MiniDrawer for Tablets (like Gmail), provide custom DrawerItems, custom colors, custom themes, ... No limits for customizations.

A quick overview of what's in it

  • the easiest possible integration
  • integrate in less than 5 minutes
  • uses the androidX support libraries
  • compatible down to API Level 16
  • includes an AccountSwitcher
  • quick and simple api
  • follows the NEW Google Material Design Guidelines
  • use vector (.svg) icons and icon fonts via the Android-Iconics integration
  • Google Material Design Icons, Google Material Community Design Icons, FontAwesome and more
  • comes with various themes which help to get your own themes clean
  • modify the colors on the go
  • comes with multiple default drawer items
  • based on a RecyclerView
  • RTL support
  • Gmail like MiniDrawer
  • expandable items
  • badge support
  • define custom drawer items
  • tested and stable
  • sticky footer or headers
  • absolutely NO limits
  • NavController support by @petretiandrea

If you upgrade from < 8.0.0 follow the MIGRATION GUIDE

Preview

Demo

You can try it out here Sample Application

Screenshots

WIKI / FAQ

You can find some frequently asked questions and other resources in the WIKI / FAQ site.

Setup

Latest releases

1. Provide the gradle dependency

implementation "com.mikepenz:materialdrawer:${lastestMaterialDrawerRelease}"

//required support lib modules
implementation "androidx.appcompat:appcompat:${versions.appcompat}"
implementation "androidx.recyclerview:recyclerview:${versions.recyclerView}"
implementation "androidx.annotation:annotation:${versions.annotation}"
implementation "com.google.android.material:material:${versions.material}"
implementation "androidx.constraintlayout:constraintlayout:${versions.constraintLayout}"

// Add for NavController support
implementation "com.mikepenz:materialdrawer-nav:${lastestMaterialDrawerRelease}"

// Add for Android-Iconics support
implementation "com.mikepenz:materialdrawer-iconics:${lastestMaterialDrawerRelease}"

v8.x.y

Major release, migrates to use the FastAdapter v5. Check out the changelog or the MIGRATION GUIDE for more details

2. Add the Drawer into the XML

The MaterialDrawerSliderView has to be provided as child of the DrawerLayout and will as such act as the slider

<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    ... your content ...

    <com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
        android:id="@+id/slider"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true" />
</androidx.drawerlayout.widget.DrawerLayout>

3. Add the DrawerStyle to your theme

<style name="SampleApp.DayNight" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    ...
    <item name="materialDrawerStyle">@style/Widget.MaterialDrawerStyle</item>
    <item name="materialDrawerHeaderStyle">@style/Widget.MaterialDrawerHeaderStyle</item>
    ...
</style>

Great. Your drawer is now ready to use.

Additional Setup

Add items and adding some functionality

//if you want to update the items at a later time it is recommended to keep it in a variable
val item1 = PrimaryDrawerItem().withIdentifier(1).withName(R.string.drawer_item_home)
val item2 = SecondaryDrawerItem().withIdentifier(2).withName(R.string.drawer_item_settings)

// get the reference to the slider and add the items
slider.itemAdapter.add(
     item1,
     DividerDrawerItem(),
     item2,
     SecondaryDrawerItem().withName(R.string.drawer_item_settings)
)

// specify a click listener
slider.onDrawerItemClickListener = { v, drawerItem, position ->
    // do something with the clicked item :D
    false
}

Selecting an item

//set the selection to the item with the identifier 1
slider.setSelection(1)
//set the selection to the item with the identifier 2
slider.setSelection(item2)
//set the selection and also fire the `onItemClick`-listener
slider.setSelection(1, true)

By default, when a drawer item is clicked, it becomes the new selected item. If this isn't the expected behavior, you can disable it for this item using withSelectable(false):

SecondaryDrawerItem().withName(R.string.drawer_item_dialog).withSelectable(false)

Modify items or the drawer

//modify an item of the drawer
item1.withName("A new name for this drawerItem").withBadge("19").withBadgeStyle(new BadgeStyle().withTextColor(Color.WHITE).withColorRes(R.color.md_red_700))
//notify the drawer about the updated element. it will take care about everything else
slider.updateItem(item1)

//to update only the name, badge, icon you can also use one of the quick methods
slider.updateName(1, "A new name")

//the result object also allows you to add new items, remove items, add footer, sticky footer, ..
slider.addItem(DividerDrawerItem())
slider.addStickyFooterItem(PrimaryDrawerItem().withName("StickyFooterItem"))

//remove items with an identifier
slider.removeItem(2)

//open / close the drawer
slider.drawerLayout?.openDrawer(slider)
slider.drawerLayout?.closeDrawer(slider)

//get the reference to the `DrawerLayout` itself
slider.drawerLayout

Add profiles and an AccountHeader

// Create the AccountHeader
headerView = AccountHeaderView(this).apply {
    attachToSliderView(slider) // attach to the slider
    addProfiles(
  ProfileDrawerItem().withName("Mike Penz").withEmail("mikepenz@gmail.com").withIcon(getResources().getDrawable(R.drawable.profile))
    )
    onAccountHeaderListener = { view, profile, current ->
        // react to profile changes
        false
    }
    withSavedInstance(savedInstanceState)
}

Use the included icon font

The MaterialDrawer provieds an extesions for the Android-Iconics library. This allows you to create your DrawerItems with an icon from any font.

Choose the fonts you need. Available Fonts build.gradle

// Add for Android-Iconics support
implementation "com.mikepenz:materialdrawer-iconics:${lastestMaterialDrawerRelease}"

// fonts
implementation 'com.mikepenz:google-material-typeface:x.y.z@aar' //Google Material Icons
implementation 'com.mikepenz:fontawesome-typeface:x.y.z@aar'     //FontAwesome

kotlin

//now you can simply use any icon of the Google Material Icons font
PrimaryDrawerItem().withIcon(GoogleMaterial.Icon.gmd_wb_sunny)
//Or an icon from FontAwesome
SecondaryDrawerItem().withIcon(FontAwesome.Icon.faw_github)

Advanced Setup

For advanced usecases. Please have a look at the provided sample activities.

Load images via url

The MaterialDrawer supports fetching images from URLs and setting them for the Profile icons. As the MaterialDrawer does not contain an ImageLoading library the dev can choose his own implementation (Picasso, Glide, ...). This has to be done, before the first image should be loaded via URL. (Should be done in the Application, but any other spot before loading the first image is working too)

Code:

//initialize and create the image loader logic
DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
    override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable) {
        Picasso.get().load(uri).placeholder(placeholder).into(imageView)
    }

    override fun cancel(imageView: ImageView) {
        Picasso.get().cancelRequest(imageView)
    }
    
    /*
    override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) {
        super.set(imageView, uri, placeholder, tag)
    }

    override fun placeholder(ctx: Context): Drawable {
        return super.placeholder(ctx)
    }

    override fun placeholder(ctx: Context, tag: String?): Drawable {
        return super.placeholder(ctx, tag)
    }
    */
})

An implementation with GLIDE v4 (See tag v6.1.1 for glide v3 sample) can be found in the sample application

Style the drawer

Custom style - styles.xml

Create your custom style. If you don't need a custom theme see the next section, how you can set the colors just by overwriting the original colors.

// define a custom drawer style
<style name="Widget.MaterialDrawerStyleCustom" parent="Widget.MaterialDrawerStyle">
    <item name="materialDrawerInsetForeground">#4000</item>
    <!-- MaterialDrawer specific values -->
    <item name="materialDrawerBackground">?colorSurface</item>
    <item name="materialDrawerPrimaryText">?android:textColorPrimary</item>
    <item name="materialDrawerPrimaryIcon">?android:textColorSecondary</item>
    <item name="materialDrawerSecondaryText">?android:textColorSecondary</item>
    <item name="materialDrawerSecondaryIcon">?android:textColorSecondary</item>
    <item name="materialDrawerDividerColor">?android:textColorHint</item>
    <item name="materialDrawerSelectedBackgroundColor">?colorPrimary</item>
</style>

// define a custom header style
<style name="Widget.MaterialDrawerHeaderStyleCustom" parent="">
    <item name="materialDrawerCompactStyle">true</item>
    <item name="materialDrawerHeaderSelectionText">?colorOnSurface</item>
    <item name="materialDrawerHeaderSelectionSubtext">?colorOnSurface</item>
</style>

// define the custom styles for the theme
<style name="SampleApp" parent="Theme.MaterialComponents.Light.NoActionBar">
    ...
    <item name="materialDrawerStyle">@style/Widget.MaterialDrawerStyleCustom</item>
    <item name="materialDrawerHeaderStyle">@style/Widget.MaterialDrawerHeaderStyleCustom</item>
    ...
</style>

Adjust BezelImageView style

Overwrite the Style of the BezelImageView for the whole MaterialDrawer

<style name="BezelImageView">
    <item name="biv_maskDrawable">@drawable/material_drawer_rectangle_mask</item>
    <item name="biv_drawCircularShadow">false</item>
    <item name="biv_selectorOnPress">@color/material_drawer_primary</item>
    <item name="android:scaleType">centerInside</item>
</style>

FAQ

How can i create a drawer without a default selection

//just set the selection to -1
slider.setSelectionAtPosition(-1)

Can I lock the Drawer

As the MaterialDrawer will just create a normal DrawerLayout (with some magic around it) everything a normal DrawerLayout can do is also available in the MaterialDrawer.

drawerLayout.setDrawerLockMode(int lockMode); //or (int lockMode, int edgeGravity)

Prefer a Kotlin DSL?

Note this is currently not compatible with v8. Thanks to @zsmb13 there's now an (in)official Kotlin DSL wrapper for the MaterialDrawer https://github.com/zsmb13/MaterialDrawerKt

Apps using the MaterialDrawer

(feel free to send me new projects)

Articles about the MaterialDrawer

Credits

Developed By

License

Copyright 2020 Mike Penz

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.