欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

如何为Android应用程序编码导航抽屉

程序员文章站 2022-06-10 19:21:40
...
如何为Android应用程序编码导航抽屉
您将要创造的

Google物料设计团队定义了Android中导航抽屉的功能,如下所示:

导航抽屉从左侧滑入,其中包含应用程序的导航目标。

实施导航抽屉的流行Android应用的一个示例是Google的Inbox应用,该应用使用导航抽屉导航到应用的不同部分。 如果您尚未在设备上安装Inbox应用,则可以自己进行检查,方法是从Google Play商店下载Inbox应用。 下面的屏幕截图显示了打开了抽屉的Inbox。

如何为Android应用程序编码导航抽屉

用户从活动的左边缘滑动手指时可以查看导航抽屉。 他们还可以通过点击操作栏中的应用程序图标(也称为“汉堡包”菜单)从家庭活动(应用程序的顶层)中找到它。

请注意,如果您的应用中有许多不同的目的地(例如,超过六个),则建议您使用导航抽屉。

在本文中,您将学习如何在Android的导航抽屉中显示导航项。 我们将介绍如何使用DrawerLayoutNavigationView API执行此任务。 另外,您还将学习如何使用Android Studio模板功能通过导航抽屉快速引导项目。

可以在我们的GitHub存储库中找到本教程的示例项目(在Kotlin中),因此您可以轻松地继续学习。

先决条件

要遵循本教程,您需要:

1.创建一个Android Studio项目

启动Android Studio并创建一个名为MainActivity的空活动的新项目(您可以将其命名为NavigationDrawerDemo )。 确保同时选中“ 包括Kotlin支持”复选框。

如何为Android应用程序编码导航抽屉

2.添加DrawerLayout和NavigationView

要在项目中开始使用DrawerLayoutNavigationView ,您需要导入设计支持以及Android支持工件。 因此,将它们添加到模块的build.gradle文件中以导入它们。

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

另外,在res / layout / activlty_main.xml文件中同时包含DrawerLayout小部件和NavigationView小部件。

<?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>

在这里,我们创建了一个ID为drawer_layout DrawerLayout小部件。 当在Android Studio设计视图中打开XML布局时, tools:openDrawer属性用于显示导航抽屉。

官方文档说了有关DrawerLayout的以下内容:

DrawerLayout充当窗口内容的顶层容器,允许从窗口的一个或两个垂直边缘拉出交互式“抽屉”视图。

添加DrawerLayout小部件后,我们包括一个指向@layout/app_bar_main的子布局。

这是我的app_bar_main.xml资源文件。 该文件仅具有CoordinatorLayoutAppBarLayoutToolbar小部件。

<?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>

最后,我们创建了NavigationView小部件。 官方文档说明了有关NavigationView的以下内容:

NavigationView代表应用程序的标准导航菜单。 菜单内容可以由菜单资源文件填充。

NavigationView XML小部件中,您可以看到我们添加了一个android:layout_gravity属性,其值为start 这用于放置抽屉-您希望抽屉从左侧或右侧出来(在支持布局方向的平台版本上,其起点或终点)。 在我们自己的情况下,抽屉将从左侧出来。

我们还包含了一个app:headerLayout属性,该属性指向@layout/nav_header_main 这将添加一个View作为导航菜单的标题。

这是我的nav_header_main.xml布局资源文件:

<?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>

此布局文件仅具有LinearLayoutImageViewTextView

如何为Android应用程序编码导航抽屉

为了包括导航抽屉的菜单项,我们可以使用属性app:menu ,其值指向菜单资源文件。

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

这是res / menu / activity_main_drawer.xml菜单资源文件:

<?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>

在这里,我们使用<menu>定义了一个Menu ,该<menu>用作菜单项的容器。 <item>创建一个MenuItem ,它表示菜单中的单个项目。

然后,我们使用<group>定义了第一个菜单组。 <group>用作<item>元素(在本例中为菜单项)的不可见容器。 每个<item>元素都有一个id,一个图标和一个标题。 请注意,当在导航抽屉中显示时,将在每个<group>的末尾绘制一条水平线。

<item>也可以包含嵌套的<menu>元素以创建子菜单-我们在上一个<item> 注意,最后一个<item>具有title属性。

请注意,当显示菜单资源中的导航列表项时,我们可以改用ListView 但是,通过使用菜单资源配置导航抽屉,我们可以免费获得导航抽屉上的材质设计样式! 如果使用ListView ,则必须维护列表并设置其样式,以符合导航抽屉推荐的材料设计规范

3.组件初始化

接下来,我们将初始化DrawerLayoutActionBarDrawerToggle实例。 初始化将在MainActivity.kt中的 onCreate()内部进行。

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)
    }

    // ... 
}

ActionBarDrawerToggle设置位于操作栏或工具栏左侧的应用程序图标,以打开和关闭导航抽屉。 为了能够创建ActionBarDrawerToggle的实例,我们必须提供以下参数:

  • 父上下文(例如,在Activity使用this ,而在Fragment调用getActivity()
  • DrawerLayout小部件的实例以链接到活动的ActionBar
  • 放置在应用程序图标上方的图标,表示有一个切换
  • 分别用于打开和关闭操作的字符串资源(用于可访问性)

我们调用的方法addDrawerListener()DrawerLayout以一个连接ActionBarDrawerToggleDrawerLayout

请注意,我们还通过setHomeButtonEnabled()启用了应用程序图标,并通过setDisplayHomeAsUpEnabled()其用于“向上”导航。

然后,我们将onPostCreate()onConfigurationChanged()onOptionsItemSelected()活动回调方法转发至切换:

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)
    }
}

根据官方文档 ,这是syncState()作用:

将抽屉指示器/状态的状态与链接的DrawerLayout同步...应该从ActivityonPostCreate方法中调用此方法,以在DrawerLayout的实例状态恢复后进行同步,以及在状态可能有所不同的任何其他时间进行同步一种不通知ActionBarDrawerToggle的方式。 (例如,如果您停止转发适当的抽屉事件一段时间。)

4.测试应用

至此,我们可以运行该应用程序了!

如何为Android应用程序编码导航抽屉

如您所见,启动该应用程序将在操作栏中显示“汉堡”导航抽屉图标。 尝试点击此应用程序图标以打开抽屉。 另外,单击导航抽屉中的项目也无济于事-我们将在下一部分中处理该部分。

5.处理点击事件

现在,让我们看看如何处理导航抽屉中每个项目的点击事件。 请注意,单击任何项​​目都应该将您带到新的“活动”或“片段”,这就是为什么将其称为导航抽屉!

首先,您的活动需要实现NavigationView.OnNavigationItemSelectedListener

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

通过实现此协定或接口,我们现在必须重写唯一的方法: 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
    }
}

选择导航菜单中的项目时,将调用此方法。 我们使用了when表达式,以根据所单击的菜单项执行不同的操作-菜单项id用作when表达式的常量。

接下来,我们必须初始化我们的NavigationView并在我们的活动的onCreate()中设置此侦听器。

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

再次运行项目!

如何为Android应用程序编码导航抽屉

当您单击某些项目时,将显示一条祝酒消息,正是我们所期望的。 但是请记住,单击项目应将用户带到新的“活动”或“片段”(为简便起见,在此我们忽略了此内容)。

您会注意到,当您单击某个项目时,抽屉仍然保留。 最好在每次单击项目时自动关闭它。 让我们看看如何做到这一点。

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
}

要关闭抽屉的链接被点击后,只需调用closeDrawer()上的一个实例DrawerLayout并通过GravityCompat.START的方法。

再运行一次项目,看看结果!

6.处理按下的后退按钮

当抽屉打开时,如果按下“ 后退”按钮,则不关闭家庭活动将是更好的用户体验。 这就是诸如Google的Inbox应用之类的流行应用的工作方式。

因此,当打开抽屉并按下“ 后退”按钮时,仅关闭抽屉而不是当前的家庭活动。 然后,如果用户再次按下“ 后退”按钮,则应关闭家庭活动。

这是我们可以实现的方法:

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

再次运行该项目并进行测试!

7.奖励:使用Android Studio模板

既然您已经了解了创建导航抽屉所涉及的API,那么我将向您展示一个快捷方式,该快捷方式将使其下次更快。 您可以简单地使用模板,而不是从头开始编写导航抽屉Activity。

Android Studio提供了遵循Android设计和开发最佳做法的代码模板。 这些现有的代码模板(在Java和Kotlin中提供)可以帮助您快速启动项目。 一个这样的模板可用于创建导航抽屉活动。

我将向您展示如何在Android Studio中使用此便捷功能。

对于新项目,启动Android Studio。

如何为Android应用程序编码导航抽屉

输入应用程序名称,然后单击下一步按钮。

您可以在“ 目标Android设备”对话框中保留默认设置。 再次单击下一步按钮。

如何为Android应用程序编码导航抽屉

在“ 向移动设备 添加 活动”对话框中,向下滚动并选择“ 导航抽屉活动”。 之后单击“ 下一步”按钮。

如何为Android应用程序编码导航抽屉

在最后一个对话框中,您可以根据需要重命名活动名称,布局名称或标题。 最后,单击“ 完成”按钮以接受所有配置。

Android Studio现在已经帮助我们创建了一个带有导航抽屉活动的项目。 真酷!

强烈建议您浏览生成的代码。

您也可以将模板用于现有的Android Studio项目。 只需转到文件>新建>活动>导航抽屉活动

如何为Android应用程序编码导航抽屉

Android Studio随附的模板非常适合简单布局和制作基本应用程序,但是如果您想进一步启动应用程序,则可以考虑Envato Market提供的一些应用程序模板

对于经验丰富的开发人员而言,它们可以节省大量时间,帮助他们从头开始创建应用程序,而将他们的才华集中在创建新应用程序的独特和定制部分上。

结论

在本教程中,您学习了如何从头开始使用DrawerLayoutNavigationView API在Android中创建导航抽屉。 我们还探讨了如何轻松快速地使用Android Studio模板创建导航抽屉。

我强烈建议您查看导航抽屉官方材料设计指南,以了解有关如何在Android中正确设计和使用导航抽屉的更多信息。

翻译自: https://code.tutsplus.com/tutorials/how-to-code-a-navigation-drawer-in-an-android-app--cms-30263