How to Code a Navigation Drawer for an Android App
2021-03-18 10:53:49 Author: code.tutsplus.com(查看原文) 阅读量:388 收藏

The material design team at Google defines the functionality of a navigation drawer in Android as follows:

The navigation drawer slides in from the left and contains the navigation destinations for your app.

An example of a popular Android app that implements the navigation drawer menu design is the Inbox app from Google, which uses a navigation drawer to navigate to different sections of the application. You can check it yourself by downloading the Inbox app from the Google Play store, if you don't already have it on your device. The screenshot below shows Inbox with the navigation drawer pulled open.

Navigation Drawer Design Android Tutorial Google Inbox Android app

The user can view the navigation drawer when they swipe a finger from the left edge of the activity. They can also find it from the home activity (the top level of the app), by tapping the app icon (also known as the Android "hamburger" menu) in the action bar. 

Note that if you have many different destinations (more than six, say) in your app, it's recommended that you use a navigation drawer menu design. 

In this post, you'll learn how to display navigation items inside a navigation drawer in Android. We'll cover how to use the DrawerLayout and NavigationView API to perform this task. For a bonus, you'll also learn how to use the Android Studio templates feature to quickly bootstrap your project with a navigation drawer. 

A sample project (in Kotlin) for this Android navigation drawer menu design tutorial can be found on our GitHub repo so you can easily follow along.

Prerequisites

To be able to follow this Android Studio navigation drawer tutorial, you'll need:

1. Create an Android Studio Project

Fire up Android Studio and create a new project (you can name it NavigationDrawerDemo) with an empty activity called MainActivity. Make sure to also check the Include Kotlin support check box. 

Android Studio Navigation Drawer Tutorial new project dialog

2. Adding the DrawerLayout and NavigationView

To begin using DrawerLayout and NavigationView in your project, you'll need to import the design support and also the Android support artifact. So add these to your module's build.gradle file to import them. 

dependencies {
    implementation 'com.android.support:design:27.0.2'
    implementation 'com.android.support:support-v4:27.0.2'
}

Also, include both the DrawerLayout widget and also the NavigationView widget in your res/layout/activlty_main.xml file.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
        xmlns:android="https://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:openDrawer="start">

    <include
            layout="@layout/app_bar_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    <android.support.design.widget.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_main"
            app:menu="@menu/activity_main_drawer" />

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

Here we created a DrawerLayout widget with the id drawer_layout. The tools:openDrawer property is used to display the navigation drawer toggle when the XML layout is open in Android Studio design view. 

The official documentation says the following about DrawerLayout:

DrawerLayout acts as a top-level container for window content that allows for interactive "drawer" views to be pulled out from one or both vertical edges of the window.

After adding the DrawerLayout widget, we included a child layout which points to @layout/app_bar_main

Here is my app_bar_main.xml resource file. This file simply has a CoordinatorLayout, an AppBarLayout, and a Toolbar widget. 

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
        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:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fitsSystemWindows="true"
            android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar_main"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>

Finally, we created a NavigationView widget. The official documentation says the following about NavigationView:

NavigationView represents a standard navigation menu for application. The menu contents can be populated by a menu resource file.

In the NavigationView XML widget, you can see that we added an android:layout_gravity attribute with value start. This is used to position the drawer—you want the navigation drawer menu design to come out from left or right (the start or end on platform versions that support layout direction). In our own case, the drawer will come out from the left. 

We also included an app:headerLayout attribute which points to @layout/nav_header_main. This will add a View as a header of the navigation menu.

Here is my nav_header_main.xml layout resource file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/nav_header"
              android:layout_width="match_parent"
              android:layout_height="160dp"
              android:background="@color/colorAccent"
              android:clickable="true"
              android:focusable="true"
              android:foreground="?attr/selectableItemBackgroundBorderless"
              android:gravity="bottom"
              android:orientation="vertical"
              android:padding="16dp"
              android:theme="@style/ThemeOverlay.AppCompat.Dark">

    <ImageView
            android:id="@+id/nav_header_imageView"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:src="@mipmap/ic_launcher" />

    <TextView
            android:id="@+id/nav_header_textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="16dp"
            android:text="Chike Mgbemena"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
</LinearLayout>

This layout file simply has a LinearLayout, an ImageView, and a TextView

Android Studio Navigation Drawer Tutorial layout preview

To include the menu items for the navigation drawer, we can use the attribute app:menu with a value that points to a menu resource file. 

<android.support.design.widget.NavigationView
        app:menu="@menu/activity_main_drawer" />

Here is the res/menu/activity_main_drawer.xml menu resource file:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group>
        <item android:id="@+id/nav_item_one"
              android:icon="@drawable/ic_drafts_black_24dp"
              android:title="Item 1" />
        <item android:id="@+id/nav_item_two"
              android:icon="@drawable/ic_drafts_black_24dp"
              android:title="Item 2" />
        <item android:id="@+id/nav_item_three"
              android:icon="@drawable/ic_drafts_black_24dp"
              android:title="Item 3" />
    </group>

    <group android:id="@+id/group_menu">
        <item android:id="@+id/nav_item_four"
              android:title="Item 4" />
        <item android:id="@+id/nav_item_five"
              android:title="Item 5" />
    </group>

    <item android:title="Title 1">
        <menu>
            <item android:id="@+id/nav_item_six"
                  android:icon="@drawable/ic_drafts_black_24dp"
                  android:title="Item 6" />
            <item android:id="@+id/nav_item_seven"
                  android:icon="@drawable/ic_drafts_black_24dp"
                  android:title="Item 7" />
        </menu>
    </item>
</menu>

Here we have defined a Menu using the <menu> which serves as a container for menu items. An <item> creates a MenuItem, which represents a single item in a menu.

We then defined our first menu group using the <group>. A <group> serves as an invisible container for <item> elements—menu items in our case. Each of the <item> elements has an id, an icon, and a title. Note that a horizontal line will be drawn at the end of each <group> for us when shown in the navigation drawer. 

A <item> can also contain a nested <menu> element in order to create a submenu—we did just this in our last <item>. Notice that this last <item> has a title property. 

Note that when showing the navigation list items from a menu resource, we could use a ListView instead. But, by configuring the navigation drawer with a menu resource, we get the material design styling on the navigation drawer for free! If you used a ListView, you'd have to maintain the list and also style it to meet the recommended material design specs for the navigation drawer

3. Initialization of Components

Next, we are going to initialize instances of our DrawerLayout and ActionBarDrawerToggle. Initialization is going to happen inside onCreate() in MainActivity.kt.

import android.content.res.Configuration
import android.os.Bundle
import android.support.v4.widget.DrawerLayout
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.view.MenuItem

class MainActivity : AppCompatActivity() {

    private lateinit var drawer: DrawerLayout
    private lateinit var toggle: ActionBarDrawerToggle

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

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

        drawer = findViewById(R.id.drawer_layout)

        toggle = ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
        drawer.addDrawerListener(toggle)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        supportActionBar?.setHomeButtonEnabled(true)
    }

    // ... 
}

The ActionBarDrawerToggle sets up the app icon located on the left of the action bar or toolbar to open and close the Android navigation drawer. To be able to create an instance of ActionBarDrawerToggle, we have to provide the following parameters: 

  • a parent context—for example, in an Activity you use this, while in a Fragment you call getActivity()
  • an instance of the DrawerLayout widget to link to the activity's ActionBar
  • the icon to place on top of the app icon to indicate that there is a drawer toggle in Android
  • the string resources for the open and close operations respectively (for accessibility)

We invoked the method addDrawerListener() on a DrawerLayout so as to connect an ActionBarDrawerToggle with a DrawerLayout

Note that we also enable the app icon via setHomeButtonEnabled() and enable it for “up” navigation via setDisplayHomeAsUpEnabled()

We then forward the onPostCreate(), onConfigurationChanged(), and onOptionsItemSelected() activity callback methods on to the drawer toggle in Android:

class MainActivity : AppCompatActivity() {

    // ... 

    override fun onPostCreate(savedInstanceState: Bundle?) {
        super.onPostCreate(savedInstanceState)
        toggle.syncState()
    }

    override fun onConfigurationChanged(newConfig: Configuration?) {
        super.onConfigurationChanged(newConfig)
        toggle.onConfigurationChanged(newConfig)
    }

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

Here is what the syncState() does, according to the official documentation

Synchronizes the state of the drawer indicator/affordance with the linked DrawerLayout... This should be called from your Activity's onPostCreate method to synchronize after the DrawerLayout's instance state has been restored, and any other time when the state may have diverged in such a way that the ActionBarDrawerToggle was not notified. (For example, if you stop forwarding appropriate drawer events for a period of time.)

4. Testing the App

At this point, we can run the app!

Android Navigation Drawer Design Tutorial First app demo

As you can see, launching the app will show the Android “hamburger” menu navigation drawer icon in the action bar. Try tapping this app icon to open the Android side menu drawer. Also, clicking on the navigation drawer items won't do anything—we're going to handle that part in the next section. 

5. Handling Click Events

Now, let's see how to handle click events for each of the items in the navigation drawer. Note that clicking on any item is supposed to take you to a new Activity or Fragment—that's why it's called a navigation drawer!

First, your activity needs to implement the NavigationView.OnNavigationItemSelectedListener

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
    // ... 
}

By implementing this contract or interface, we must now override the only method: onNavigationItemSelected()

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
    
    // ... 

    override fun onNavigationItemSelected(item: MenuItem): Boolean {

        when (item.itemId) {
            R.id.nav_item_one -> Toast.makeText(this, "Clicked item one", Toast.LENGTH_SHORT).show()
            R.id.nav_item_two -> Toast.makeText(this, "Clicked item two", Toast.LENGTH_SHORT).show()
            R.id.nav_item_three -> Toast.makeText(this, "Clicked item three", Toast.LENGTH_SHORT).show()
            R.id.nav_item_four -> Toast.makeText(this, "Clicked item four", Toast.LENGTH_SHORT).show()
        }
        return true
    }
}

This method is invoked when an item in the navigation menu is selected. We used the when expression to perform different actions based on the menu item that was clicked—the menu item ids serve as constants for the when expression. 

Next, we have to initialize our NavigationView and set this listener inside onCreate() of our activity. 

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
    // ...
    override fun onCreate(savedInstanceState: Bundle?) {
        // ... 
        val navigationView: NavigationView = findViewById(R.id.nav_view)
        navigationView.setNavigationItemSelectedListener(this)
        // ... 
    }
// ... 

Run the project again!

Android Navigation Drawer Design Tutorial App demo with navigation item clicks configuration

When you click on some items, a toast message is displayed—just what we expected. But remember that clicking on an item should take the user to a new Activity or Fragment (we ignored this here for brevity's sake). 

You'll notice that when you click on an item, the Android side menu drawer still remains. It would be better if it closed automatically anytime an item was clicked. Let's see how to do that. 

override fun onNavigationItemSelected(item: MenuItem): Boolean {

    when (item.itemId) {
        R.id.nav_item_one -> Toast.makeText(this, "Clicked item one", Toast.LENGTH_SHORT).show()
        R.id.nav_item_two -> Toast.makeText(this, "Clicked item two", Toast.LENGTH_SHORT).show()
        R.id.nav_item_three -> Toast.makeText(this, "Clicked item three", Toast.LENGTH_SHORT).show()
        R.id.nav_item_four -> Toast.makeText(this, "Clicked item four", Toast.LENGTH_SHORT).show()
    }
    drawer.closeDrawer(GravityCompat.START)
    return true
}

To close the drawer after a link has been clicked, simply invoke closeDrawer() on an instance of DrawerLayout and pass GravityCompat.START to the method. 

Run the project one more time and see the result! 

6. Handling the Back Button Being Pressed

When the drawer is open, it would be a better user experience not to close the home activity if the Back button is pressed. This is the way popular apps like Google's Inbox app work. 

So, when the drawer menu design is open and the Back button is pressed, only close the drawer instead of the current home activity. Then, if the user presses the Back button again, the home activity should be closed. 

Here's how we can achieve this: 

override fun onBackPressed() {
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START)
    } else {
        super.onBackPressed()
    }
}

Run the project again and test it out! 

7. Bonus: Using Android Studio Templates

Now that you've learnt about the APIs involved to create a navigation drawer, I'll show you a shortcut that will make it faster next time. You can simply use a template instead of coding a navigation drawer Activity from scratch. 

Android Studio provides code templates that follow the Android design and development best practices. These existing code templates (available in Java and Kotlin) can help you quickly kick-start your project. One such template can be used to create a navigation drawer activity. 

I'll show you how to use this handy feature in Android Studio. 

For a new project, fire up Android Studio. 

Android Navigation Drawer Design Tutorial Create Android Project dialog

Enter the application name and click the Next button. 

You can leave the defaults as they're in the Target Android Devices dialog. Click the Next button again. 

Android Navigation Drawer Design Tutorial Add an Activity to Mobile dialog

In the Add an Activity to Mobile dialog, scroll down and select Navigation Drawer Activity. Click the Next button after that. 

Android Navigation Drawer Design Tutorial Configure Activity dialog

In the last dialog, you can rename the Activity name, layout name or title if you want. Finally, click the Finish button to accept all configurations. 

Android Studio has now helped us to create a project with a navigation drawer activity. Really cool!

You're strongly advised to explore the code generated. 

You can use templates for an already existing Android Studio project too. Simply go to File > New > Activity > Navigation Drawer Activity.  

Android Navigation Drawer Design Tutorial Navigation from file menu too Navigation Drawer Activity

Top Android App Templates With Navigation Drawers From CodeCanyon

The templates that come included with Android Studio are good for simple layouts and making basic apps, but if you want to kick-start your app even further, you might consider some of the app templates available from Envato Market

They’re a huge time saver for experienced developers, helping them to cut through the slog of creating an app from scratch and focus their talents instead on the unique and customised parts of creating a new app.

Here are just a small handful of the thousands of Android app templates available on CodeCanyon. If there's one that piques your interest, you can easily get started by making a purchase.

1. Grocery and Vegetable Delivery Android App with Admin Panel

If you or your client have a food delivery business, getting an app up and running is crucial. That's why you should consider this multi-store grocery service app template. It includes three templates with stunning layouts and Android hamburger menus. There's no limit to the categories you can add, and you can also SMS and email order notifications.

Grocery and Vegetable Delivery Android App Template

2. Universal—Full Multi-Purpose Android App

Buying the Universal Android app template is just like downloading a Swiss Army knife. It can do it all, from WordPress and Facebook to Twitter and Soundcloud. In fact, there is a list of more than 15 content providers that this template supports. Users can access important information from the slick side menu design and easily make their way around their favorite sites.

Universal Multi Purpose Android App Template

3. MaterialX—Android Material Design UI Components 2.7

MaterialX is a recommended download for any app developer. It includes more than 315 unique UI components across more than 31 categories. Create stunning Android side menu designs, buttons, dialog boxes, and more from this single download. If you want a quick way to add some much-needed style to your new project, get this template.

MaterialX Android Material Design UI Components Download

4. Universal Android WebView App

Do you have content hosted online that you want to turn into a mobile experience? Then check out the Universal Android WebView App template. It was developed in Android Studio and supports phones and tablets running Android 4.1 and above. The Android navigation drawer menu design is completely customizable, as are other components. It also supports AdMob for monetization.

Universal Android WebView App Template

5. Android Wallpapers App

Here's a cool Android app template that's useful if you want to get your creative designs out into the world. The Android Wallpapers app supports static images, GIFs, and 4K photos. This template also includes useful features like:

  • pinch to zoom
  • push notifications
  • AdMob advertisement support
  • Android Studio code
Android Wallpapers App Template

Find More Useful Android App Templates From Envato Tuts+

CodeCanyon is home to thousands of Android app templates across many different niches. You're free to browse around and find one for your project. But it's worth noting that our Envato Tuts+ instructors have done a lot of that work for you already. You can check out some of these articles to explore the world of Android app templates that you can start using today:

Conclusion

In this tutorial, you learned how to create a navigation drawer menu design in Android using the DrawerLayout and NavigationView API from scratch. We also explored how easily and quickly it is use the Android Studio templates to create a navigation drawer. 

I highly recommend checking out the official material design guidelines for navigation drawers to learn more about how to properly design and use navigation drawers in Android.   

To learn more about coding for Android, check out some of our other courses and tutorials here on Envato Tuts+!

This post has been updated with contributions from Nathan Umoh. Nathan is a staff writer for Envato Tuts+.


文章来源: https://code.tutsplus.com/tutorials/how-to-code-a-navigation-drawer-in-an-android-app--cms-30263
如有侵权请联系:admin#unsafe.sh