Android SideMenu 1- Navigation Drawer

In this article we're going to create side menu with Navigation Drawer which is very common and used in plenty of apps. You click to toggle button to open/close it or swipe through. After creating new project the first thing we need to do change our layout from and to use DrawerLayout as the root layout of the xml file.

Note: If you're not using the latest version of the android studio and androidX you need to add the material design dependency. Depending on the version you're using you may not need to add it or android studio will ask to add in case you need it.

Everytime we'd like to create navigation drawer we need to use it within drawerlayout otherwise it is not going to work. Let's remove the default layout and use drawer layout as the root layout and give it an id.

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!--
    This is a comment
    the views will be placed here
    -->
</androidx.drawerlayout.widget.DrawerLayout>

DrawerLayout should only contain 2 views. One for the particular activity/fragment and the 2. is for the navigation drawer. I created Constraint Layout for the activity and it has 2 views inside, textview and imageview. The 2. view is navigationview. I'm using autosizing Textview attributes for the textview. And also width and height is 0dp which will take places as much as there's space on the parent layout unless there is margin or other affective attribute. In that case using percentage for the textview height so it's going to be 15% of the screen and the text size will expand properly to that space. **app:layout_constraintHeight_percent="0.15".

Imageview I'm using percentages for the imageview too. app:layout_constraintWidth_percent="0.80" means it'll take 80% of the screen width and app:layout_constraintHeight_percent="0.40" 40% of the height.

We are going to create headerLayout and menu for the navigationview in the next steps. Here's my xml code:

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!--
    This is a comment
    the views will be placed here
    -->

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/textView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:text="Android"
            android:textAlignment="center"
            android:textColor="@color/black"
            app:autoSizeMaxTextSize="100sp"
            app:autoSizeMinTextSize="18sp"
            app:autoSizeStepGranularity="2sp"
            app:autoSizeTextType="uniform"
            app:layout_constraintBottom_toTopOf="@id/imageView"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHeight_percent="0.15"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent" />

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:contentDescription="@string/todo"
            android:src="@drawable/android"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHeight_percent="0.40"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintWidth_percent="0.80" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    <com.google.android.material.navigation.NavigationView
       android:id="@+id/navigationView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        app:headerLayout="@layout/header"
         app:menu="@menu/header_menu"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"/>
</androidx.drawerlayout.widget.DrawerLayout>

Since the headerLayout and menu not created yet we get an error. Let's create the navigation header file. (named header). Right click to Layout folder new=>Layout Resource file and name it exactly same we did in xml. (header). It just has height 100dp and background color of purple.

header.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:background="@color/purple_500" />

Next step is to create the menu which we named header_menu. Right click to res folder new=>Android Resource file and name it exactly same we did in xml. (header_menu) and select Menu for the Resource Type. Here, we are going to create our menu items.

header_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/option1"
        android:title="Option 1" />

    <item
        android:id="@+id/option2"
        android:title="Option 2" />

    <item
        android:id="@+id/option3"
        android:title="Option 3" />

    <item
        android:id="@+id/option4"
        android:title="Option 4" />

    <item
        android:id="@+id/option5"
        android:title="Option 5" />
</menu>

The next step is to create toggle button to be able to open and close the menu that needs to be done in the activity/fragment. We need to use ActionBarDrawerToggle to accomplish that. It's going to take parameters as the activity, drawerLayout and string resources.

mainActivity

package com.cobanogluhasan.navigationdrawer

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.drawerlayout.widget.DrawerLayout

class MainActivity : AppCompatActivity() {

    //lateinit means it will be initialized later
    lateinit var toggleButton: ActionBarDrawerToggle

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

        val navigationView = findViewById<NavigationView>(R.id.navigationView)
        val drawer = findViewById<DrawerLayout>(R.id.drawer)
        toggleButton = ActionBarDrawerToggle(this, drawer, R.string.open, R.string.close)
        //add the toggle button to drawerLayout
        drawer.addDrawerListener(toggleButton)
        //it's ready to used
        toggleButton.syncState()

        //enable the toggle button on the UI it's false by default
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
    }

    //in order to make our toggle and menu items work we need to override  onOptionsItemSelected

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (toggleButton.onOptionsItemSelected(item)) {
            return true
        }
        return super.onOptionsItemSelected(item)
    }
}

If we run the application we can see that the side menu working, opening and closing via clicking toggleButton. It's also swipeable which is default feature of the navigation drawer. One thing is missing, nothing happens if we click to menu options. Time to handle that. Simply add NavigationItemSelectedListener to onCreate. It includes only when expression and when the proper option is called, execute the toast function.

setNavigationItemSelectedListener

        navigationView.setNavigationItemSelectedListener {
            when (it.itemId) {
                R.id.option1 -> toast("option 1")
                R.id.option2 -> toast("option 2")
                R.id.option3 -> toast("option 3")
                R.id.option4 -> toast("option 4")
                R.id.option5 -> toast("option 5")
            }
            true
        }

toast

    fun toast(text: String) {
        Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
    }

Now out side menu is complete! I hope you enjoyed this article. Thanks for reading, let me know if you have any suggestion/feedback. Happy Coding!

Source Code: navigationDrawer