The side menu (or Navigation Drawer) is a key element of the interface of most modern Android applications. It allows users to quickly navigate between sections without cluttering the main screen. If you are just starting to develop applications in Android Studiocreating such a menu may seem like a daunting task. However, with the right approach and step-by-step guide, the process becomes clear even for beginners.

In this article we will look at how to add a side menu to your application, customize its appearance and functionality, and avoid common mistakes. You will learn which components Material Design to use, how to integrate menus with Fragment i Activity, and what tools Android Studio will simplify your work. It doesnโ€™t matter whether you are creating a simple application or a complex project - Navigation Drawer will become an integral part of your UI.

What is a Navigation Drawer and why do you need it?

Side menu (Navigation Drawer) is a panel that slides out from the left (less often right) edge screen by swiping or clicking on the โ€œhamburgerโ€ icon (โ˜ฐ). It has become the standard Material Design for applications with multiple partitions, such as Gmail, Google Drive or YouTube. Main advantages:

  • ๐Ÿ“ฑ Saving screen space โ€”the main content is not overloaded with navigation buttons.
  • ๐Ÿ”„ Ease of switching โ€”the user can quickly go to any section of the application.
  • ๐ŸŽจ Design flexibility โ€”supports icons, headers, submenus and even animations.
  • ๐Ÿ”ง Standardization โ€”users are already accustomed to this type of navigation, which reduces the barrier to entry.

From a technical point of view, Navigation Drawer is implemented through a combination of several components:

  • DrawerLayout โ€” a container that controls the sliding of the menu.
  • NavigationView โ€” a widget for displaying menu items.
  • Toolbar or AppBar โ€” a toolbar with a menu icon.
  • Menu โ€” an XML file with a description of the menu items.

Without a side menu, applications with a large number of sections risk losing convenience. For example, imagine without the ability to quickly switch between โ€œGames,โ€ โ€œApplications,โ€ and โ€œLibrary.โ€ This is why Google Play Market without the ability to quickly switch between โ€œGamesโ€, โ€œApplicationsโ€ and โ€œLibraryโ€. That's why Navigation Drawer so popular among developers.

๐Ÿ“Š Which interface element do you most often use in your applications?
Bottom Navigation
Navigation Drawer
Tabs
Other

Preparing a project in Android Studio

Before adding a side menu, make sure your project is configured correctly. Here are the minimum requirements:

  • ๐Ÿ“Œ Android Studio version 2022.2.1 or later (to support the latest libraries).
  • ๐Ÿ“ฑ Minimum SDK version not lower API 21 (Android 5.0 Lollipop).
  • ๐Ÿ”ง B file build.gradle (Module: app) libraries must be included Material Components:
dependencies {

implementation 'com.google.android.material:material:1.9.0'

implementation 'androidx.appcompat:appcompat:1.6.1'

implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

}

If you are creating a project from scratch, select a template Empty Activity โ€”this will simplify further configuration. If the project already exists, check that it is using Theme.MaterialComponents in the file themes.xml:

<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">

Also make sure that AndroidManifest.xml is set to the correct theme for Application:

<application

android:theme="@style/Theme.MyApplication"

...>

๐Ÿ’ก

If you are updating an old project, use Migration to AndroidX in the menu Refactor Android Studio to avoid library conflicts.

Creating a layout with Navigation Drawer

Now let's move on to practice. The main layout file is activity_main.xml. Open it and replace the content with the following 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_layout"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MainActivity">

<LinearLayout

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

<androidx.appcompat.widget.Toolbar

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="?attr/actionBarSize"

android:background="?attr/colorPrimary"

android:elevation="4dp"

android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

<FrameLayout

android:id="@+id/fragment_container"

android:layout_width="match_parent"

android:layout_height="match_parent"/>

</LinearLayout>

<com.google.android.material.navigation.NavigationView

android:id="@+id/nav_view"

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:layout_gravity="start"

app:headerLayout="@layout/nav_header"

app:menu="@menu/nav_menu"/>

</androidx.drawerlayout.widget.DrawerLayout>

Pay attention to the key elements:

  • DrawerLayout โ€” the root container that controls the slide-out of the menu.
  • Toolbar โ€” the toolbar, on which the menu icon will be displayed.
  • FrameLayout โ€” a container for dynamically loading fragments.
  • NavigationView โ€”the side menu itself with links to nav_header (header) and nav_menu (menu items).

Now create two new ones file:

  1. res/layout/nav_header.xml โ€” menu title layout (for example, with a user avatar).
  2. res/menu/nav_menu.xml โ€” XML file with menu items.

Add DrawerLayout to activity_main.xml|

Create Toolbar for menu icon|

Add FrameLayout for fragments|

Create NavigationView with links to nav_header and nav_menu|

Check library connection Material Components-->

Setting menu items and header

File nav_menu.xml defines which items will be displayed in the side menu. An example of a simple menu with three sections:

<?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/nav_home"

android:icon="@drawable/ic_home"

android:title="Home"/>

<item

android:id="@+id/nav_gallery"

android:icon="@drawable/ic_gallery"

android:title="Gallery"/>

<item

android:id="@+id/nav_slideshow"

android:icon="@drawable/ic_slideshow"

android:title="Slideshow"/>

</group>

<menu>

<item

android:id="@+id/nav_share"

android:icon="@drawable/ic_share"

android:title="Share"/>

<item

android:id="@+id/nav_send"

android:icon="@drawable/ic_send"

android:title="Send feedback"/>

</menu>

</item>

</menu>

Key attributes:

  • android:checkableBehavior="single" โ€” allows you to highlight the currently selected item.
  • android:icon โ€” icon for menu item (must be in the folder res/drawable).
  • android:title โ€”the text that will be displayed.

For the menu title (nav_header.xml) you can use the following template:

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

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="180dp"

android:background="?attr/colorPrimary"

android:gravity="bottom"

android:orientation="vertical"

android:padding="16dp"

android:theme="@style/ThemeOverlay.AppCompat.Dark">

<ImageView

android:id="@+id/imageView"

android:layout_width="60dp"

android:layout_height="60dp"

android:src="@drawable/ic_profile"/>

<TextView

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="Username"

android:textAppearance="@style/TextAppearance.AppCompat.Body1"

android:textColor="@android:color/white"/>

<TextView

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="user@example.com"

android:textAppearance="@style/TextAppearance.AppCompat.Body2"

android:textColor="@android:color/white"/>

</LinearLayout>

Important: height header (android:layout_height) is better to set fixed (for example, 180dp) to avoid problems with display on different devices.

Where can I get icons for the menu?

Icons for Navigation Drawer can be downloaded from official website Material Design Icons (https://material.io/resources/icons/) or use built-in Android Studio via Vector Asset Studio (RMB by folder res/drawable โ†’ New โ†’ Vector Asset).

Integration with MainActivity

Now Let's connect the layout with the application logic. Open the file MainActivity.kt (or MainActivity.java) and add the following code:

class MainActivity : AppCompatActivity() {

private lateinit var drawerLayout: DrawerLayout

private lateinit var navView: NavigationView

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

// Initializing Toolbar

val toolbar: Toolbar = findViewById(R.id.toolbar)

setSupportActionBar(toolbar)

supportActionBar?.setDisplayHomeAsUpEnabled(true)

// Initializing DrawerLayout and NavigationView

drawerLayout = findViewById(R.id.drawer_layout)

navView = findViewById(R.id.nav_view)

// Setting the menu icon

toolbar.setNavigationIcon(R.drawable.ic_menu)

toolbar.setNavigationOnClickListener {

drawerLayout.openDrawer(GravityCompat.START)

}

// Processing clicks on menu items

navView.setNavigationItemSelectedListener { menuItem ->

when (menuItem.itemId) {

R.id.nav_home -> {

supportFragmentManager.beginTransaction()

.replace(R.id.fragment_container, HomeFragment())

.commit()

menuItem.isChecked = true

}

R.id.nav_gallery -> {

supportFragmentManager.beginTransaction()

.replace(R.id.fragment_container, GalleryFragment())

.commit()

menuItem.isChecked = true

}

R.id.nav_slideshow -> {

supportFragmentManager.beginTransaction()

.replace(R.id.fragment_container, SlideshowFragment())

.commit()

menuItem.isChecked = true

}

}

drawerLayout.closeDrawer(GravityCompat.START)

true

}

}

// Processing clicks on the "Back" button

override fun onBackPressed() {

if (drawerLayout.isDrawerOpen(GravityCompat.START)) {

drawerLayout.closeDrawer(GravityCompat.START)

} else {

super.onBackPressed()

}

}

}

In this code:

  • ๐Ÿ”ง It is initialized Toolbar and set as ActionBar.
  • ๐Ÿ“Œ The menu icon (ic_menu) and the handler for its click are configured.
  • ๐Ÿ”„ The logic of switching between fragments when selecting menu items is implemented.
  • ๐Ÿ”™ Adds processing for the "Back" button to close the menu.

Don't forget to create fragment classes (HomeFragment, GalleryFragment, SlideshowFragment) or replace them with your own. Example of a simple fragment:

class HomeFragment : Fragment() {

override fun onCreateView(

inflater: LayoutInflater, container: ViewGroup?,

savedInstanceState: Bundle?

): View? {

return inflater.inflate(R.layout.fragment_home, container, false)

}

}

๐Ÿ’ก

Always check that DrawerLayout closes when clicking on a menu item (drawerLayout.closeDrawer()), otherwise the user will remain with an open menu after selecting a section.

Adding animations and customization

Standard Navigation Drawer can be improved with animations and styles. For example, to make the menu slide out smoothly, add the following style to styles.xml following style:

<style name="DrawerArrowStyle" parent="@style/Widget.AppCompat.DrawerArrowToggle">

<item name="spinBars">true</item>

<item name="color">@android:color/white</item>

</style>

Then apply it to the menu icon in MainActivity:

val toggle = ActionBarDrawerToggle(

this, drawerLayout, toolbar,

R.string.navigation_drawer_open,

R.string.navigation_drawer_close

)

drawerLayout.addDrawerListener(toggle)

toggle.syncState()

To customize the appearance NavigationView use attributes in activity_main.xml:

<com.google.android.material.navigation.NavigationView

...

app:itemIconTint="@color/nav_menu_icon_color"

app:itemTextColor="@color/nav_menu_text_color"

app:itemBackground="@drawable/nav_menu_item_background"/>

Where:

  • nav_menu_icon_color โ€” icon color (for example, @color/black).
  • nav_menu_text_color โ€” text color.
  • nav_menu_item_background โ€” menu item background when hovering (you can use selector).

Example file res/drawable/nav_menu_item_background.xml to change the background when when pressed:

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

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@color/colorPrimaryLight" android:state_pressed="true"/>

<item android:drawable="@android:color/transparent"/>

</selector>

๐Ÿ’ก

To make the menu open smoothly, add android:windowAnimationStyle to the theme of an application with custom animation.

Typical mistakes and how to avoid them

When working with Navigation Drawer developers often encounter the following problems:

Problem Cause Solution
Menu does not open by swipe Not specified android:layout_gravity="start" for NavigationView Add an attribute to the layout or check that DrawerLayout is the root element
Menu icon is not displayed Not called setSupportActionBar(toolbar) or not set setNavigationIcon() Check initialization Toolbar and the presence of an icon in res/drawable
The application crashes when you click on a menu item Not implemented setNavigationItemSelectedListener or an error in Fragment Add an event handler and check the correctness of transactions with fragments
The menu opens on top of the keyboard DrawerLayout does not take into account android:fitsSystemWindows Add android:fitsSystemWindows="true" to the root DrawerLayout
Menu items are not highlighted when selected Not specified android:checkableBehavior="single" in nav_menu.xml Add an attribute to the group of menu items

Another common mistake is memory leak when opening/closing the menu frequently. To avoid this, always close DrawerLayout after selecting an item:

drawerLayout.closeDrawer(GravityCompat.START)

Also make sure that fragments are not duplicated when you repeatedly click on the same menu item. To do this, add a check:

if (menuItem.itemId != navView.menu.findItem(R.id.nav_home).itemId) {

// Loading a new fragment

}

How to debug problems with Navigation Drawer?

Use Logcat in Android Studio to find errors. Filter logs by tag "DrawerLayout" or "NavigationView". If the menu does not respond to swipes, check if another element is blocking it (for example, RecyclerView with horizontal scrolling).

Optimization for different screens

The side menu should display correctly on devices with different screen sizes - from smartphones to tablets. Here are some adaptation tips:

  • ๐Ÿ“ฑ For smartphones: use the standard menu width (wrap_content or a fixed value, for example 320dp).
  • ๐Ÿ–ฅ๏ธ For tablets: you can increase the menu width to 400dp or make it always open (mode locked open).
  • ๐Ÿ”„ For folding devices: check the behavior of the menu when changing the screen orientation.

To have the menu automatically adjust to the screen size, add to values i values-sw600dp different styles. For example, for tablets (res/values-sw600dp/styles.xml):

<style name="NavigationViewStyle" parent="@style/Widget.Design.NavigationView">

<item name="android:layout_width">400dp</item>

</style>

To support dark theme add alternative colors to res/values-night/colors.xml:

<color name="nav_menu_background">#212121</color>

<color name="nav_menu_text_color">#FFFFFF</color>

And apply them in the layout:

app:itemTextColor="@color/nav_menu_text_color"

app:itemIconTint="@color/nav_menu_text_color"

app:backgroundTint="@color/nav_menu_background"

๐Ÿ’ก

Always test the side menu on devices with different screen sizes. Use Android Studio Emulator with profiles Pixel 5 (smartphone) and Pixel C (tablet).

FAQ: Frequently asked questions about Navigation Drawer

How to make the menu open on the right?

Change android:layout_gravity="start" to android:layout_gravity="end" to NavigationViewAlso update the menu opening handler:

drawerLayout.openDrawer(GravityCompat.END)
Is it possible to add dynamic ones to the menu? items?

Yes, use NavigationView.getMenu().add() in runtime. Example:

navView.menu.add("Dynamic item").setIcon(R.drawable.ic_dynamic)

Don't forget to update the handler clicks.

How to change the color of the status bar when the menu is open?

Add to styles.xml:

<item name="android:statusBarColor">@android:color/transparent</item>

And set the flag View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR to MainActivity:

window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
Why does the menu open on top of the keyboard?

Add to AndroidManifest.xml for Activity:

android:windowSoftInputMode="adjustResize|adjustPan"

Or programmatically hide the keyboard before opening the menu:

val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager

imm.hideSoftInputFromWindow(currentFocus?.windowToken, 0)

How to add animation when opening a menu?

Create an animation file res/anim/slide_in.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android">

<translate

android:duration="300"

android:fromXDelta="-100%"

android:toXDelta="0%" />

</set>

And apply it to DrawerLayout:

drawerLayout.setScrimColor(Color.TRANSPARENT)

drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {

override fun onDrawerSlide(drawerView: View, slideOffset: Float) {

drawerView.translationX = slideOffset * drawerView.width

}

// Leave other methods empty

})