Android Custom Navigation Drawer Tutorial

Now it is time for me to share how to create a simple Android custom Navigation Drawer. Basically, Navigation Drawer is a sliding menu from left or right of the mobile screen. There are so many apps that use this kind of menu so it is a must for you to learn it, well I’m gonna share it here right now!

To add a Navigation Drawer to Android app, you have to use a DrawerLayout as a root of the UI layout container. I will use a very basic and simple example here so that you can understand it quickly. I’m gonna use only one Activity class for this tutorial.

What the app will look like?

The app will look like this after you finish this tutorial:

Android Custom Navigation Drawer Tutorial

The image above is what we will create here, the first one is a left navigation drawer and the second on the right is right navigation drawer, so you will create both of them!

What will you learn?

  • Creating a simple Android custom navigation drawer, both left and right navigation drawer.
  • Using a RecyclerView inside a navigation drawer

 

Note: In this post, I used Android Studio 3.3, make sure you use the latest Android Studio, or if you already install it, be sure to check the latest update. The Kotlin version that I used is Kotlin 1.3.20.

 

Getting Started

Open your Android Studio and choose to Start a new Android Studio Project. After that set the Application Name CustomNavDrawer and don’t forget to check the Include Kotlin Support checkbox. After that give the Activity Name MainActivity and wait until the Android Studio finishes preparing your project.

Open your app/build.gradle file, add the implementation of RecyclerView implementation 'com.android.support:recyclerview-v7:28.0.0' inside the dependencies block code like this:

dependencies {
   implementation fileTree(dir: 'libs', include: ['*.jar'])
   implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
   implementation 'com.android.support:appcompat-v7:28.0.0'
   implementation 'com.android.support.constraint:constraint-layout:1.1.3'

   implementation 'com.android.support:recyclerview-v7:28.0.0'

   testImplementation 'junit:junit:4.12'
   androidTestImplementation 'com.android.support.test:runner:1.0.2'
   androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

 

Why we have to include a RecyclerView here? Because we will learn to use it inside our right nav drawer later. If you want to learn about how to use Android RecyclerView, you can check my other post here.

Next, open the styles.xml inside res directory and replace the DarkActionBar to NoActionBar like this:

<?xml version="1.0" encoding="utf-8"?>
<resources>

   <!-- Base application theme. -->
   <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
       <!-- Customize your theme here. -->
       <item name="colorPrimary">@color/colorPrimary</item>
       <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
       <item name="colorAccent">@color/colorAccent</item>
   </style>

</resources>

 

Creating Navigation Drawer Layouts

Add a new layout named left_drawer_menu.xml to your project:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="#3C3C3C"
   android:fillViewport="true">

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

       <LinearLayout
           android:id="@+id/navHeader"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:orientation="vertical"
           android:background="#414141"
           android:paddingTop="30dp"
           android:paddingBottom="20dp"
           android:gravity="center">

           <ImageView
               android:id="@+id/ivProfile"
               android:layout_width="80dp"
               android:layout_height="80dp"
               android:src="@drawable/ic_profile_picture"/>

           <TextView
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:textColor="@android:color/white"
               android:textSize="18sp"
               android:layout_marginTop="10dp"
               android:text="River Hill"/>

           <TextView
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:textColor="#9E9E9E"
               android:textSize="14sp"
               android:layout_marginTop="4dp"
               android:text="View Profile"/>

       </LinearLayout>

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

           <TextView
               android:layout_width="match_parent"
               android:layout_height="60dp"
               android:gravity="center_vertical"
               android:textColor="#CCCCCC"
               android:drawableLeft="@drawable/ic_home"
               android:drawablePadding="20dp"
               android:paddingLeft="20dp"
               android:paddingRight="20dp"
               android:textStyle="bold"
               android:textSize="16sp"
               android:background="?selectableItemBackground"
               android:clickable="true"
               android:text="Home"/>

           <View
               android:layout_width="match_parent"
               android:layout_height="1dp"
               android:background="#4E4E4E" />

           <TextView
               android:layout_width="match_parent"
               android:layout_height="60dp"
               android:gravity="center_vertical"
               android:textColor="#CCCCCC"
               android:drawableLeft="@drawable/ic_followers"
               android:drawablePadding="20dp"
               android:paddingLeft="20dp"
               android:paddingRight="20dp"
               android:textStyle="bold"
               android:textSize="16sp"
               android:background="?selectableItemBackground"
               android:clickable="true"
               android:text="Followers"/>

           <View
               android:layout_width="match_parent"
               android:layout_height="1dp"
               android:background="#4E4E4E" />

           <TextView
               android:layout_width="match_parent"
               android:layout_height="60dp"
               android:gravity="center_vertical"
               android:textColor="#CCCCCC"
               android:drawableLeft="@drawable/ic_transaction"
               android:drawablePadding="20dp"
               android:paddingLeft="20dp"
               android:paddingRight="20dp"
               android:textStyle="bold"
               android:textSize="16sp"
               android:background="?selectableItemBackground"
               android:clickable="true"
               android:text="Transactions"/>

           <View
               android:layout_width="match_parent"
               android:layout_height="1dp"
               android:background="#4E4E4E" />

           <TextView
               android:layout_width="match_parent"
               android:layout_height="60dp"
               android:gravity="center_vertical"
               android:textColor="#CCCCCC"
               android:drawableLeft="@drawable/ic_settings"
               android:drawablePadding="20dp"
               android:paddingLeft="20dp"
               android:paddingRight="20dp"
               android:textStyle="bold"
               android:textSize="16sp"
               android:background="?selectableItemBackground"
               android:clickable="true"
               android:text="Setting"/>

           <View
               android:layout_width="match_parent"
               android:layout_height="1dp"
               android:background="#4E4E4E" />

       </LinearLayout>

   </LinearLayout>

</ScrollView>

 

The left nav drawer will only display a custom layout that shows a profile picture and name, and menus like homepage, settings, etc.

Next, and another new layout named right_drawer_menu.xml here:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="#3C3C3C"
   android:fillViewport="true">

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

       <TextView
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:gravity="center_vertical"
           android:textColor="@android:color/white"
           android:paddingLeft="20dp"
           android:paddingRight="20dp"
           android:layout_marginTop="20dp"
           android:layout_marginBottom="10dp"
           android:textStyle="bold"
           android:textSize="16sp"
           android:background="?selectableItemBackground"
           android:clickable="true"
           android:text="Favorites"
           android:textAllCaps="true"/>

       <View
           android:layout_width="match_parent"
           android:layout_height="1dp"
           android:background="#4E4E4E" />

       <android.support.v7.widget.RecyclerView
           android:id="@+id/rvFavorites"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"/>

   </LinearLayout>

</ScrollView>

 

In this right nav drawer layout, I included a RecyclerView that will show a favorite list, but we will show the data later.

After that, open your activity_main.xml and replace the entire code like this:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
   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:fitsSystemWindows="true"
   tools:openDrawer="start"
   android:id="@+id/drawerLayout">

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

   <include layout="@layout/left_drawer_menu"
       android:layout_width="300dp"
       android:layout_height="match_parent"
       android:layout_gravity="start"
       android:id="@+id/leftDrawerMenu"/>

   <include layout="@layout/right_drawer_menu"
       android:layout_width="250dp"
       android:layout_height="match_parent"
       android:layout_gravity="end"
       android:id="@+id/rightDrawerMenu"/>

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

 

Inside the activity_main.xml here I include a DrawerLayout as a root layout and this is required for the nav drawer to work. The difference between the left and right nav drawer is on the layout gravity attribute. The left one uses android:layout_gravity="start" and the right one uses layout_gravity="end".

Create a new layout named content_main.xml that will contain our custom header that displays a nav drawer icon and favorite list icon.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="55dp"
       android:orientation="horizontal"
       android:background="@color/colorPrimary"
       android:gravity="center_vertical">

       <ImageView
           android:id="@+id/ivNavMenu"
           android:layout_width="wrap_content"
           android:layout_height="match_parent"
           android:src="@drawable/ic_nav_drawer"
           android:paddingLeft="12dp"
           android:paddingRight="12dp"/>

       <TextView
           android:layout_width="0dp"
           android:layout_height="wrap_content"
           android:layout_weight="1"
           android:textColor="@android:color/white"
           android:paddingRight="20dp"
           android:paddingLeft="10dp"
           android:textStyle="bold"
           android:textSize="18sp"
           android:text="Homepage"/>

       <ImageView
           android:id="@+id/ivFavoriteList"
           android:layout_width="wrap_content"
           android:layout_height="match_parent"
           android:src="@drawable/ic_favorite"
           android:paddingLeft="12dp"
           android:paddingRight="12dp"/>

   </LinearLayout>

   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:textStyle="bold"
       android:textSize="20sp"
       android:layout_centerInParent="true"
       android:text="Custom Nav Drawer"/>

</RelativeLayout>

 

Writing the Activity Code

Now we already create the layout, the next step is modifying the MainActivity.kt file:

package com.thesimplycoder.customnavdrawer

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.content_main.*
import kotlinx.android.synthetic.main.right_drawer_menu.*

class MainActivity : AppCompatActivity() {

   private val favoriteList = ArrayList<String>()
   lateinit var adapter: FavoriteAdapter

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)

       // set on click listener to left navigation icon
       ivNavMenu.setOnClickListener {
           toggleLeftDrawer()
       }

       // set on click listener to right navigation icon
       ivFavoriteList.setOnClickListener {
           toggleRightDrawer()
       }
   }

   private fun toggleLeftDrawer() {
       if (drawerLayout.isDrawerOpen(leftDrawerMenu)) {
           drawerLayout.closeDrawer(leftDrawerMenu)
       } else {
           drawerLayout.openDrawer(leftDrawerMenu)
       }
   }

   private fun toggleRightDrawer() {
       if (drawerLayout.isDrawerOpen(rightDrawerMenu)) {
           drawerLayout.closeDrawer(rightDrawerMenu)
       } else {
           drawerLayout.openDrawer(rightDrawerMenu)
       }
   }
}

 

I added two functions to toggle the left and right drawer, so when you click the nav drawer icon, it will open the left nav drawer. When you click a heart or favorite icon, it will open the right nav drawer. Instead of clicking the icon, you can also swipe from the left or right of the page to open the navigation drawer too! Awesome right!

Android Custom Navigation Drawer Tutorial

 

Setting up the Favorite Lists

You will notice we haven’t set up the favorite list data inside the right nav drawer right? So we will set this up now. Create a new layout named item_favorite.xml for our adapter layout.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="wrap_content">

   <TextView
       android:id="@+id/tvFavorite"
       android:layout_width="match_parent"
       android:layout_height="60dp"
       android:drawableLeft="@drawable/ic_heart"
       android:drawablePadding="20dp"
       android:gravity="center_vertical"
       android:textColor="#CCCCCC"
       android:paddingLeft="20dp"
       android:paddingRight="20dp"
       android:textStyle="bold"
       android:textSize="16sp"
       android:background="?selectableItemBackground"
       android:clickable="true"/>

   <View
       android:layout_width="match_parent"
       android:layout_height="1dp"
       android:background="#4E4E4E" />

</LinearLayout>

 

Next, create a new Kotlin class file FavoriteAdapter.kt and it will become the adapter class of favorite list RecyclerView.

package com.thesimplycoder.customnavdrawer

import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.item_favorite.view.*

class FavoriteAdapter(private val itemList: List<String>) : RecyclerView.Adapter<FavoriteAdapter.ViewHolder>() {

   override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FavoriteAdapter.ViewHolder {
       val view = LayoutInflater.from(parent.context).inflate(R.layout.item_favorite, parent,
           false)
       return ViewHolder(view)
   }

   override fun getItemCount(): Int {
       return itemList.size
   }

   override fun onBindViewHolder(holder: FavoriteAdapter.ViewHolder, position: Int) {
       holder.bind()
   }

   inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

       fun bind() {
           val favorite = itemList.get(adapterPosition)
           itemView.tvFavorite.text = favorite
       }
   }
}

 

Back to MainActivity.kt and update the onCreate() method and add the RecyclerView implementation like this:

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)

   // init favorite data
   favoriteList.add("Sport")
   favoriteList.add("Movie")
   favoriteList.add("Travelling")
   favoriteList.add("Reading")
   favoriteList.add("News")
   favoriteList.add("Marketing")
   favoriteList.add("Technology")
   favoriteList.add("Trending")

   // init adapter
   adapter = FavoriteAdapter(favoriteList)

   // init recyclerview
   rvFavorites.layoutManager = LinearLayoutManager(this)
   rvFavorites.adapter = adapter
   rvFavorites.isNestedScrollingEnabled = false

   // set on click listener to left navigation icon
   ivNavMenu.setOnClickListener {
       toggleLeftDrawer()
   }

   // set on click listener to right navigation icon
   ivFavoriteList.setOnClickListener {
       toggleRightDrawer()
   }
}

 

Tada! Your app will now display the favorite list inside the right navigation drawer!

Android Custom Navigation Drawer Tutorial

Where to go next?

You can download this full code from my GitHub repo here. Be sure to check my other post here about creating a simple Image Gallery application and how to create an Android Tab application. Hope you like my post, comment and share it with love!

You may also like...

1 Response

  1. f.n says:

    thank you so much

Join the discussion...

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: