乐趣区

关于android:导航组件概览-MAD-Skills

这是一个新的系列文章,咱们称之为 “Modern Android Development 技巧 ”,简称为 “MAD Skills”。本系列文章致力于帮忙开发者们打造更好的古代 Android 开发体验,敬请关注。明天为大家公布本系列文章中的第一篇: 导航 (Navigation) 组件概览。

概览

本文会简要概述导航组件,包含如何创立一个带有导航能力的、已启用导航的 UI 中无关蕴含层级的细节的新利用,以及对于一些次要 API 和导航组件工作原理的解释。

对于导航组件,网上曾经有一些不错的内容材料:

  • 官网的入门教程
  • Ian Lake 最近公布的视频
  • Android 中文教学视频: Android Jetpack 导航组件

撰写本章是为了本系列接下来的内容铺垫一些基础知识。

导航组件介绍

导航组件包含了相干 API 和 Android Studio 中的设计工具,其大大简化了您利用中导航流程的创立和编辑。以前没有导航组件的时候,利用中的导航工作是由咱们手动编码实现的。您可能须要在每一个 UI 元素触发的导航动作代码中增加一个监听器,并编写代码使之启动一个 intent 来展现一个新 activity,或者切换到一个 Fragment。

您还须要在用户点击设备返回按钮和 ActionBar 的向上按钮时正确地解决返回和向上操作。有时候不同利用中解决这两个相干而又不完全相同的操作会产生一些不统一的后果。

有了导航组件后,咱们能够应用其标准化的 API 以及 IDE 中的可视化工具,这些都能够帮忙咱们使整个导航流程更清晰、更简略以及更对立。您能够应用设计工具来创立导航目的地 (destination) 并定义导航门路,以及在您利用的导航图中切换目的地的相干操作 (action)。之后,您能够增加相干代码,使用户和利用的交互对应到适合的导航操作 (action) 上。

让咱们来创立一个利用,并通过理论的工具和代码来体验一下导航组件。

导航模板

自 3.6 版本后,Android Studio 蕴含了一个十分有用的新性能,这就是将导航整合到创立新利用的模板中。这一性能并不是应用导航组件库所必须的,但它能够帮忙汇合所有必要的模块,从而极大地简化了创立新利用时应用导航的流程。

咱们将应用这些模板之一的 Basic Activity 模板来创立一个新利用。除此之外的其余一些模板也自带导航,不过咱们临时先应用这个模板。

这个模板会帮咱们创立一个蕴含导航组件根底构造的利用。咱们还会失去两个目的地 (destination),以及定义了它们彼此之间导航门路的导航图。

IDE 加载结束该利用之后,关上导航资源文件 nav_graph.xml 并在 Design 模式 (此外还有 Code 与 Split 模式) 下查看。您会看到以后利用导航图的样子。

您会发现两个目的地: FirstFragment 是那个被设置为初始页或者叫首页的目的地。SecondFragment 是另外那个咱们能够导航到的目的地。

Basic Activity 模板能够创立两个目的地

点选这些目的地,您能够从左边的属性表单中查看它们的相干信息,比方下图中展现了这个目的地应用了 Fragment 类。

在之前图表的导航图中,您还能够发现两个目的地之间的箭头,它们定义了导航图中可能的导航操作 (action)。其中包含了从 FirstFragmentSecondFragment 的导航,以及从 SecondFragment 返回 FirstFragment 的导航。

操作 (action) 定义了可能的导航,但其不指定导航产生的工夫,该逻辑存在于您的代码中。所以当用户点击某界面元素并须要触发导航的时候,您应该调用导航 API 应用其中一个操作来导航到图中的一个目的地。

操作还能够被用来定义传入目的地的参数,以及从源目的地和目的地进入退出的转场动画。咱们会在之后的视频中介绍更多对于这些属性的内容,您也能够从 导航文档 – Navigation 组件应用入门 中理解更多对于它们的信息。

咱们能够用导航工具来定义新的目的地,当咱们还没有筹备好目的地的 Fragment 类的时候,咱们能够用占位符,也能够应用已存在的 Fragment 类。通过定义目的地以及它们对应的操作,您能够更直观地设计利用的所有界面跳转流程。

然而,代码呢?

到目前为止,咱们始终在应用图形化工具开发导航,而像 Android Studio 中所有的资源文件一样,这些都是通过 XML 代码实现的,所以您也能够间接查看和编辑这些代码。如果在工具中切换到代码 (Code) 模式,您会发现如下的 XML 代码:

<?xml version="1.0" encoding="utf-8"?>
<navigation
    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/nav_graph"
    app:startDestination="@id/FirstFragment">
    <fragment
        android:id="@+id/FirstFragment"
        android:name="com.android.samples.navoverviewarticle.FirstFragment"
        android:label="@string/first_fragment_label"
        tools:layout="@layout/fragment_first">
        <action
            android:id="@+id/action_FirstFragment_to_SecondFragment"
            app:destination="@id/SecondFragment" />
    </fragment>
    <fragment
        android:id="@+id/SecondFragment"
        android:name="com.android.samples.navoverviewarticle.SecondFragment"
        android:label="@string/second_fragment_label"
        tools:layout="@layout/fragment_second">
        <action
            android:id="@+id/action_SecondFragment_to_FirstFragment"
            app:destination="@id/FirstFragment" />
    </fragment>
</navigation>

您会发现导航图的代码构造其实非常简单。其中作为根元素的 navigation,既定义了整个导航的构造,也包含了 起始目的地 (start destination) (或称之为 home destination)。在导航图中的每个目的地都是 fragment,每个目的地都包含 0 个或更多的 操作 (action),操作定义了如何导航到导航图中的其余目的地。

Basic Activity 模板同时还创立了在两个目的地彼此之间导航的示例代码。举个例子,当用户点击 UI 中的按钮,FirstFragment 蕴含的如下代码会被触发:

override fun onViewCreated(view: View, savedInstanceState: Bundle?){super.onViewCreated(view, savedInstanceState)
    view.findViewById<Button>(R.id.button_first)
        .setOnClickListener {findNavController()
             .navigate(R.id.action_FirstFragment_to_SecondFragment)
    }
}

在这里调用 navigate() 办法,并传入在导航图中定义的 action_FirstFragment_to_SecondFragment 作为参数,会使利用导航到第二个目的地。

您能够运行利用并点击相干按钮 (或者返回按钮,该按钮会被主动插入导航返回事件) 来察看后果:

运行利用并应用 Next/Previous 按钮和返回按钮来导航

导航 UI 层次结构

我发现,察看 UI 中的各个局部在蕴含层级中的互相关系对于了解它们如何一起工作非常有帮忙。为了查看这个局部,让咱们来应用 Navigation Drawer Activity 模板创立另一个新工程。

当 Android Studio 加载利用结束后,运行该利用您会看到如下图所示:

利用 Navigation Drawer Activity 模板创立的利用

和之前咱们应用 Basic Activity 模板创立的利用不同,这个利用没有能够点击并导航到下一个目的地的按钮。取而代之的是在 DrawerLayout 中能够触发导航的菜单选项:

这一次,导航是由抽屉式导航栏中的菜单项触发的

当用户点击 DrawerLayout 中的菜单项时,利用会导航至和那些菜单项关联的目的地。这是因为导航组件主动绑定了菜单项和对应的目的地,所以您不用手动编写代码来创立这些链接。

让咱们来看一下使这所有胜利运行的 UI 层次结构。为了查看它,咱们须要应用 Android Studio 中的 布局查看器 (Layout Inspector) 来分析这个利用的 UI。

从工具 (Tools) 菜单启动布局查看器 (Layout Inspector)

布局查看器 (Layout Inspector) 让咱们能够以图形化的形式查看整个利用的视图层次结构,同时咱们也能够看到每一个容器及视图的属性。您应该能够看到如下图所示:

图中蓝色的矩形批示着以后被选中视图 (在上图示例中,DecorView 中的顶层 LinearLayout) 的边界。

其实咱们本能够查看整个利用的层次结构 (而且我也非常激励大家这么做,这有助于可视化规范视图层级中所产生的事),然而我只想抉择几个特定的视图来解释。首先,让咱们看一下 ConstraintLayout 视图:

ConstraintLayout 容器是在 main_activity.xml 布局文件中被定义的,它蕴含了利用的理论内容 (但并不是所有内容,比方像 ActionBar 这种被模板创立好的元素)。在该容器中,咱们能够看到 NavHostFragment 元素:

NavHostFragment 是应用导航组件时产生魔力的源泉,当用户在 fragment 之间导航的时候,它是 fragment 目的地被替换进出的容器。

另一个我想特地指出的是 NavigationView:

这个视图目前在右边屏幕外,它是一个 NavigationDrawer 并且其菜单选项被用来在目的地之间导航。该视图当初是不可见的,咱们须要点击 ActionBar 菜单按钮来将它显示到屏幕上。

导航部件

咱们曾经在层级构造中查看了几个 UI 组件,以及它们彼此之间是如何关联的,接下来我想介绍一下几个重要部件,导航组件正是利用它们来在目的地之间实现导航。

一开始应用导航组件的时候,我发现有几个中央很让人蛊惑,因为很多部件都应用 Navigation 和 Nav 这样的字眼,并且有些居然比导航组件库自身存在的还要早。所以我感觉了解这些次要的部件是什么以及它们彼此的关系应该会很有帮忙。

利用容器

为了图解这些部件是如何整合的,我会应用一个简化的利用容器的略图:

“ 工程师美术作品 ” 展现了利用内容的略图

咱们会发现 Toolbar 在顶部,其中包含了 ActionBar 菜单按钮。而后利用内容存在于下方,其中包含了 NavHostFragment,而 NavHostFragment 包含了以后目的地的 UI。

NavHostFragment

正如我后面提到的,NavHostFragment 是导航时大量操作产生的中央。它是一个被导航组件用来替换进出目的地 fragment 的容器。当您在利用中导航到一个指定的 fragment 目的地时,NavHostFragment 会将其内容替换为那个指定的 fragment。

NavController

NavController 是一个被导航组件应用的外部部件,其在幕后起着决定性的作用。当用户在利用中导航的时候,NavController 在导航组件库中把握着解决 NavHostFragment 替换进出目的地 fragment 的逻辑。

NavigationView

利用展现了 NavigationView (抽屉式导航栏) 笼罩在 activity 内容上方

接下来是 NavigationView,它是一个从右边划入的抽屉式导航栏。它在导航图中提供了一个可能目的地的菜单栏。NavigationView 其中一个很酷的个性是,您能够应用菜单项的 ID 主动地导航到对应菜单项关联的目的地,从而防止了手动创立基于菜单抉择的反复代码。

有一点须要留神的是 NavigationView 存在于 NavHostFragment 容器之外,它自身并不是一个目的地,而只是一个指定利用导航目的地的路径。另外值得关注的一点是,早在其被导航组件整合进导航系统之前,这个 API 曾经存在并被应用了很长一段时间。

NavigationUI

这个导航组件的部件被用来更新 NavHostFragment 以外的 UI。大部分的导航相干的图像更新产生在 NavHostFragment 外部,然而零碎中依然存在其余须要更新且不在容器内的部件,比方咱们下面看到的抽屉式导航栏,以及相似 tab bar 的元素 (该组件能够被用来展现以后目的地信息)。

总结

这篇文章只是对于导航组件的一个疾速概览,目标是为了让您体验如何创立一个能够应用导航性能的利用,以及看一下这种利用的大抵构造。在将来的文章和视频中,针对如何同特定导航 API 进行交互,我会介绍更多的技术细节,比方导航到对话框目的地、应用 SafeArgs 以及解决深层链接。

更多信息

想理解更多对于导航组件的信息,请查阅 developer.android.google.cn 上的教程 Navigation 组件应用入门。

退出移动版