Contents

Create a sliding menu in Android

Use the navigation architecture component from Android Jetpack

The navigation drawer is a UI panel that shows your app’s main navigation menu. It is open when the user swipes a finger from the left edge of the screen or, when the hamburger menu icon is used from the action bar.

Firstly, start by creating a project with an empty activity.

Setup your project


Add dependencies
1
2
implementation "android.arch.navigation:navigation-fragment-ktx:1.0.0-alpha06"
implementation "android.arch.navigation:navigation-ui-ktx:1.0.0-alpha06"

❗ If you have the following error

All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes). Found versions 28.0.0-rc02, 27.1.1. Examples include com.android.support:animated-vector-drawable:28.0.0-rc02 and com.android.support:design:27.1.1 less… (Ctrl+F1) There are some combinations of libraries, or tools and libraries, that are incompatible, or can lead to bugs. One such incompatibility is compiling with a version of the Android support libraries that is not the latest version (or in particular, a version lower than your targetSdkVersion). Issue id: GradleCompatible.

You can solve the problem by renaming all libraries that are added by default into your dependencies with the mapping from developer.android.com to use the new AndroidX librairies.

For instance, you should do the following renaming

1
2
"com.android.support:appcompat-v7" ➡️ "androidx.appcompat:appcompat:1.0.0-rc2"
"com.android.support.constraint:constraint-layout" ➡️ "androidx.constraintlayout:constraintlayout:2.0.0-alpha2"

Add also the following properties into gradle.properties

1
2
android.useAndroidX=true
android.enableJetifier=true

According to the documentation, android.useAndroidX means that you want to start using AndroidX into your project. android.enableJetifier means that you want to have tool support (from the Android Gradle plugin) to automatically convert existing third-party libraries as if they were written for AndroidX.

❗ Be careful to use classes from androidx package into generated code and into layout rather than old classes to avoid compilation errors.

Enable navigation editor

Click File/Settings, select the Experimental category in the left pane, check Enable Navigation Editor, and then restart Android Studio.

Define items for the sliding menu


Create the menu resource file by Right-Click on the res folder, then select New/Android Resource File. Fill the dialog box with drawer_items as file name and select Menu as resource type. Add the following items into the menu file

1
2
3
4
5
6
<group  android:checkableBehavior="single">
        <item android:title="Item1" android:id="@+id/fragmentItem1"/>
        <item android:title="Item2" android:id="@+id/fragmentItem2"/>
        <item android:title="Item3" android:id="@+id/fragmentItem3"/>
        <item android:title="Item4" android:id="@+id/fragmentItem4"/>
</group>

group is an optional, invisible container for item elements. It allows you to categorize menu items so they share properties such as active state and visibility.

Define fragments used by the application


Create 4 fragments named FragmentItem[1,2,3,4], with their layout named fragment_item[1,2,3,4] by Right-Click on the res folder, then select New/Fragment/Fragment (blank). These fragments will be used as targets of menu items.

Create another fragement named FragmentMainUI with his layout named fragement_main_ui that will be the main UI of the application when no menu item will be selected.

Into each layout, put a TextView to identify them

1
2
3
4
5
6
<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_vertical|center_horizontal"
    android:text="ITEM 1"
    android:textAppearance="@style/TextAppearance.AppCompat.Display1" />

Define navigation graph


Create a navigation graph file by Right-Click on the res folder, then select New/Android Resource File. Fill the dialog box with nav_graph as file name and select Naviguation as resource type.

Into the graph editor, add all destinations previously created (all fragments). Set the destination FragmentMainUI as Start destination, the navigation graph should looks like

/post/2018/09/create-sliding-menu-with-naviguation-aac/img/NavigationGraph.png

Use a ToolBar instead of the built-in application bar


To be compliant with material design guideline, we must use ToolBar instead of using the built-in application bar to manage hamburger icon. ToolBar can be add into your layout by using

1
2
3
4
5
<androidx.appcompat.widget.Toolbar
        android:id="@+id/toolBar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary" />

Do not forget to set your app theme to one without built-in action bar. For this, update the android:theme attribute into Manifest.xml.

1
2
3
<application
    ...
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>

To finish, set the ToolBar as the application bar into onCreate() of your MainActivity:

1
setSupportActionBar(toolBar)

Define the application layout


Replace the content of activity_main.xml by the following layout.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?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"
    android:id="@+id/navDrawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Layout of main content UI, drawer will slide over this -->
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id="@+id/overview_coordinator_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolBar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary" />
        </com.google.android.material.appbar.AppBarLayout>

        <RelativeLayout
            android:id="@+id/mainLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <fragment
                android:id="@+id/navDrawerActivity"
                android:name="androidx.navigation.fragment.NavHostFragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:defaultNavHost="true"
                app:navGraph="@navigation/nav_graph" />
        </RelativeLayout>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>

    <!-- Contents of drawer -->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/drawer_items" />
</androidx.drawerlayout.widget.DrawerLayout>

The layout is divided into two parts, the content of the drawer that is a NavigationView and the main UI where the drawer will slide over. The main UI is composed by a ToolBar and a NavHostFragment. This last component is an empty view whereupon destinations are swapped in and out as a user navigates through your app. You must associate this component with a navigation graph by using app:navGraph attribute.

Tie destinations to menu items


You can tie destinations to the navigation drawer by using the id of the destination as the same id for the navigation drawer menu item in XML. For instance, uses id fragmentItem1 in the following way to tie Item1 menu with FragmentItem1. drawer_items.xml must look like.

1
2
3
4
5
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    ...
        <item android:title="Item1" android:id="@+id/fragmentItem1"/>
    ...
</menu>

fragment_item1.xml must look like.

1
2
3
4
5
6
<FrameLayout 
    android:id="@+id/fragmentItem1"
    ...
    >
    ...
</FrameLayout> 

And nav_graph.xml must look like.

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<navigation 
    ...
    <fragment
        android:id="@+id/fragmentItem1"
    ...
</navigation>

Do the same for all menus and destinations that you want to tie.

The Navigation Architecture Component includes a NavigationUI class. This class has several static methods you can use to connect menu items with navigation destinations. For example, add the following code into MainActivity class to connect items in the menu drawer to the navigation view after that you have correctly defined all ids.

1
NavigationUI.setupWithNavController(navView, findNavController(R.id.navDrawerActivity))

Enable hamburger icon

In order to enable and show the hambuger icon, you can add setUpDrawerToggle() into MainActivity and call the method into onCreate()

1
2
3
4
5
6
private fun setUpDrawerToggle() {
    val mDrawerToggle = object : ActionBarDrawerToggle(this, navDrawer, toolBar,
            R.string.open, R.string.close) {}
    navDrawer.addDrawerListener(mDrawerToggle)
    mDrawerToggle.syncState()
}

ActionBarDrawerToggle is the easiest way to tie together the functionality of DrawerLayout and ActionBar to implement the recommended design for navigation drawers.