Implement a Navigation Drawer with a Toolbar on Android

Navigation drawer is a great UI pattern recommended by Google when you design your Android application. Introduced with Android Lollipop, the Toolbar widget is a flexible way to customize easily the action bar. In this tutorial, you’re going to learn how to implement a navigation drawer with a toolbar on Android.

1. Get Material Colors

First, you need to get material colors for your application. A website like http://www.materialpalette.com can be useful to create quickly your material colors file. Here, we choose green and light green as primary colors :


<?xml version="1.0" encoding="utf-8"?>
<resources>
  <color name="primary">#4CAF50</color>
  <color name="primary_dark">#388E3C</color>
  <color name="primary_light">#C8E6C9</color>
  <color name="accent">#8BC34A</color>
  <color name="primary_text">#212121</color>
  <color name="secondary_text">#727272</color>
  <color name="icons">#FFFFFF</color>
  <color name="divider">#B6B6B6</color>
</resources>

Put your XML resource file, got from Material Palette, in the folder res/values of your Android project.

 

2. Configure your dependencies

Now, it’s time to configure dependencies in your build.gradle file. You need to import the following libraries :


com.android.support:appcompat-v7:23.3.0
com.android.support:design:23.3.0

 

3. Create a No Action Bar theme

To use the Toolbar widget, you need to create a No Action Bar theme for your activity. In your styles.xml file under res/values, you can create the following theme :


<resources>
  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primary_dark</item>
    <item name="colorAccent">@color/accent</item>
  </style>

  <style name="MyAppTheme" parent="@style/AppTheme" />
</resources>

To enable some specific properties available from API V21, you need to create a folder named values-v21 and override the MyAppTheme like that :


<resources>
  <style name="MyAppTheme" parent="AppTheme">
    <item name="android:windowContentTransitions">true</item>
    <item name="android:windowAllowEnterTransitionOverlap">true</item>
    <item name="android:windowAllowReturnTransitionOverlap">true</item>
    <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
    <item name="android:windowSharedElementExitTransition">@android:transition/move</item>
  </style>
</resources>

Finally, you need to apply the MyAppTheme to a specific Activity with a Toolbar widget or if you want to your entire application :


<application
  android:theme="@style/MyAppTheme" >
...
</application>

 

4. Create layout for the Toolbar

The Toolbar widget has been created to play the role that was dedicated to Action Bar previously. It can be used to hold :

  • Action menu
  • App title and subtitle
  • Navigation button(s)

Like the Toolbar will be used between several activities’ layouts, we create a separate layout file and apply our specific configuration with colors for example :


<android.support.v7.widget.Toolbar
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@+id/toolbar"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  android:background="@color/primary"
  app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
  app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

Now, we could include the Toolbar in each activity and have just one place to change its configuration.

 

5. Add the Navigation Drawer to the Activity

Navigation Drawer is a great UI pattern recommended by Google when you develop Android applications. It’s a great way to organise navigation inside an application. Implementation is easy and we need to use DrawerLayout widget to implement it.

The layout of our main Activity will be like that :


<?xml version="1.0" encoding="utf-8"?>
<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"
 >

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include layout="@layout/toolbar" />

    <!-- For fragments -->
    <FrameLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:id="@+id/frame"/>

  </LinearLayout>

  <android.support.design.widget.NavigationView
    android:id="@+id/navigation"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:menu="@menu/nav_items" />

</android.support.v4.widget.DrawerLayout>

Here, you can note that we include the Toolbar widget defined at the step 4.

 

6. Create a navigation items menu

To define the content of the navigation drawer, we can define a navigation items menu in res/menu :


<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <group android:checkableBehavior="single">
    <item android:id="@+id/refresh"
      android:title="@string/refresh"
      android:icon="@drawable/ic_action_refresh" />

    <item android:id="@+id/stop"
      android:title="@string/stop"
      android:icon="@drawable/ic_action_stop" />
  </group>
</menu>

Here, we define juste two entries in the menu.

 

7. Configure Toolbar and Navigation Drawer in Activity

All the resources file are ready. So, it’s time to configure Toolbar and Navigation Drawer in the Activity. It’s easy and we use dedicated method named configureToolbar and configureNavigationDrawer :


import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.RelativeLayout;

public class MainActivity extends AppCompatActivity {

  private RelativeLayout layout;
  private DrawerLayout drawerLayout;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    layout = (RelativeLayout) findViewById(R.id.layout);
    configureNavigationDrawer();
    configureToolbar();
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.empty_menu, menu);
    return true;
  }

  private void configureToolbar() {
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    ActionBar actionbar = getSupportActionBar();
    actionbar.setHomeAsUpIndicator(R.drawable.ic_action_menu_white);
    actionbar.setDisplayHomeAsUpEnabled(true);
  }

  private void configureNavigationDrawer() {
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    NavigationView navView = (NavigationView) findViewById(R.id.navigation);
    navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
      @Override
      public boolean onNavigationItemSelected(MenuItem menuItem) {

        Fragment f = null;
        int itemId = menuItem.getItemId();

        if (itemId == R.id.refresh) {
          f = new RefreshFragment();
        } else if (itemId == R.id.stop) {
          f = new StopFragment();
        }

        if (f != null) {
          FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
          transaction.replace(R.id.frame, f);
          transaction.commit();
          drawerLayout.closeDrawers();
          return true;
        }

        return false;
     }
    });
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    int itemId = item.getItemId();

    switch(itemId) {
      // Android home
      case android.R.id.home:
        drawerLayout.openDrawer(GravityCompat.START);
      return true;

      // manage other entries if you have it ...
    }

    return true;
  }
}

As you can see, it’s really simple to assemble all the pieces of the puzzle to have a functional application with a Navigation Drawer and a Toolbar.

If you have some questions about the content of fragments used here, it’s really simple. For example, this is the content of the RefreshFragment :


import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment1 extends Fragment {

  @Nullable
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.refresh_fragment_layout, container, false);
    return v;
  }
}

After that, it’s your job to complete the fragment with your content.

 

8. Demo

Now, it’s time for demo of the application created. Some screenshots :

material_drawer_1

 

material_drawer_2

 

material_drawer_3

 

9. Bonus

In bonus, you can follow this tutorial in a live coding video available in two parts on Youtube :

 

Leave a Reply