The Android Design Support Library makes life a lot easier for developers wishing to comply to the Material Design Guidelines with their app. To use it, simply add a dependency to your module’s gradle.build file:
compile 'com.android.support:design:23.0.1'
Before releasing this library, in many cases developers needed to write the code for implementing material design in their apps themselves or they had to rely on community-created libraries – the navigation drawer being one of these components. Now, the Design Support Library provides a NavigationView, which makes adding a pre-styled drawer straight forward.
As before, you need a DrawerLayout as top-element in your Activity layout. The first child element is your main layout, while the second child element is the layout, which gets rendered in the slide-in drawer. This is the place where you can use the new NavigationView element.
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <!-- your content layout --> <android.support.design.widget.NavigationView android:id="@+id/nav_drawer" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/drawer_header" app:menu="@menu/drawer"/> </android.support.v4.widget.DrawerLayout>
A custom header layout can be applied via app:headerLayout. You have to consider that the header height needs to adapt when the drawer is under a transparent status bar (which is possible from KitKat on). To achieve this, declare a <dimen> resource. Now you can add a values-v19 dimensions resource file, where you override this resource to take the additional space of the status bar into account.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="@dimen/navdrawer_header_height"> <ImageView android:layout_height="match_parent" android:layout_width="match_parent" android:src="@drawable/img_navdrawer_header" android:scaleType="centerCrop" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_margin="16dp" android:text="@string/drawer_header_text" /> </FrameLayout>
Also, you have to provide a menu via app:menu. You can also have multiple groups. For example, the first group can be used for navigating the main screens of your app, the second group can contain things like settings.
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:id="@+id/group_1" android:checkableBehavior="single"> <item android:id="@+id/navitem_1" android:checked="true" android:icon="@drawable/ic_navitem_1" android:title="@string/navitem_1"/> <item android:id="@+id/navitem_2" android:icon="@drawable/ic_navitem_2" android:title="@string/navitem_2"/> </group> <group android:id="@+id/group_2" android:checkableBehavior="none"> <item android:id="@+id/navitem_3" android:title="@string/navitem_3" /> <item android:id="@+id/navitem_4" android:title="@string/navitem_4" /> </group> </menu>
Now the layout is all set up. The last step is to register a listener with your activity, so you get a callback when menu items are clicked. There you mark the clicked item as checked, execute your item specific code (replace fragments, …) and finally close the drawer.
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { DrawerLayout mDrawerLayout; NavigationView mNavigationView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mNavigationView = (NavigationView) findViewById(R.id.nav_drawer); mNavigationView.setNavigationItemSelectedListener(this); } @Override public boolean onNavigationItemSelected(MenuItem menuItem) { menuItem.setChecked(true); switch(menuItem.getItemId()) { case R.id.navitem_1: { // Do something (replace fragments, …) break; } } mDrawerLayout.closeDrawer(mNavigationView); return false; } }
Easy as that. With minimum effort you have a working Material Design navigation drawer in your app.