导航: 嵌套导航图和 <include> | MAD Skills

简介: 在本系列之前的文章中,我们增加了咖啡记录功能,使用导航 UI 提高了用户体验,并且实现了有条件导航。在本文中,我们将了解如何通过使用嵌套图管理导航图,并且使用 include 标签来引入其他图。这就需要我们将应用模块化,并且了解导航如何在模块间实现操作。那么,接下来,让我们打开 Android Studio 开始学习如何在模块上使用导航吧。

嵌套导航图
我们从导航图开始。嵌套图允许您在父导航图中将一系列目的地页面分组。

我们看一眼导航图,coffeeList 和 coffeeEntryDialog 目的地页面非常适合转换为嵌套图。要达成这个目的,我这里长按 shift 并且同时选择 "Move to Nested Graph" (移动到嵌套图):

将 coffeeList 和 coffeeEntryDialogFragment 移动到嵌套图

现在我们回到代码界面,您可以看到嵌套图仅仅是根图中的新导航图:

<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"
   app:startDestination="@id/donutList">

   <fragment
       android:id="@+id/donutList"
       android:name="com.android.samples.donuttracker.donut.DonutList"
       android:label="@string/donut_list" >
       <action
           android:id="@+id/action_donutList_to_donutEntryDialogFragment"
           app:destination="@id/donutEntryDialogFragment" />
       <action
           android:id="@+id/action_donutList_to_selectionFragment"
           app:destination="@id/selectionFragment" />
   </fragment>
   <dialog
       android:id="@+id/donutEntryDialogFragment"
       android:name="com.android.samples.donuttracker.donut.DonutEntryDialogFragment"
       android:label="DonutEntryDialogFragment">
       <deepLink app:uri="myapp://navdonutcreator.com/donutcreator" />
       <argument
           android:name="itemId"
           app:argType="long"
           android:defaultValue="-1L" />
   </dialog>
   <fragment
       android:id="@+id/selectionFragment"
       android:name="com.android.samples.donuttracker.setup.SelectionFragment"
       android:label="@string/settings"
       tools:layout="@layout/fragment_selection" >
       <action
           android:id="@+id/action_selectionFragment_to_donutList"
           app:destination="@id/donutList" />
   </fragment>
   <navigation
       android:id="@+id/coffeeGraph"
       app:startDestination="@id/coffeeList">
       <fragment
           android:id="@+id/coffeeList"
           android:name="com.android.samples.donuttracker.coffee.CoffeeList"
           android:label="@string/coffee_list">
           <action
               android:id="@+id/action_coffeeList_to_coffeeEntryDialogFragment"
               app:destination="@id/coffeeEntryDialogFragment" />
       </fragment>
       <dialog
           android:id="@+id/coffeeEntryDialogFragment"
           android:name="com.android.samples.donuttracker.coffee.CoffeeEntryDialogFragment"
           android:label="CoffeeEntryDialogFragment">
           <argument
               android:name="itemId"
               android:defaultValue="-1L"
               app:argType="long" />
       </dialog>
   </navigation>
</navigation>

所选择的 Fragment 之间的导航被迁移至嵌套图中。

嵌套图必须包含 id。您可以使用这个 id 实现导航到嵌套图的代码,但并不是直接转换到其子目的地页面。嵌套图包含自己的启动目的地页面,并且请不要分开暴露它们的子目的地页面。

<navigation
   android:id="@+id/coffeeGraph"
   app:startDestination="@id/coffeeList">

如果您双击嵌套图,就可以发现嵌套的目的地页面和它们之间的操作。

Include 标签
除了使用嵌套图之外,我还可以提取图到新的导航 xml 文件中。我在这里创建了一个新的 xml 文件,名称为 coffee_graph,并且将嵌套图的内容迁移到这个文件中。

<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/coffeeGraph"
   app:startDestination="@id/coffeeList">
   <fragment
       android:id="@+id/coffeeList"
       android:name="com.android.samples.donuttracker.coffee.CoffeeList"
       android:label="@string/coffee_list">
       <action
           android:id="@+id/action_coffeeList_to_coffeeEntryDialogFragment"
           app:destination="@id/coffeeEntryDialogFragment" />
   </fragment>
   <dialog
       android:id="@+id/coffeeEntryDialogFragment"
       android:name="com.android.samples.donuttracker.coffee.CoffeeEntryDialogFragment"
       android:label="CoffeeEntryDialogFragment">
       <argument
           android:name="itemId"
           android:defaultValue="-1L"
           app:argType="long" />
   </dialog>
</navigation>

我可以通过 include 标签将新的图嵌套到其他文件中。虽然使用 include 标签在功能上与使用嵌套图相同,但您还可以使用其他项目模块或者库项目的图。

<include app:graph="@navigation/coffee_graph"/>

和嵌套图相类似,引用的图不会暴露目的地页面的列表,也就是说我需要更新菜单 id 来指向 coffeeList。

<item
   android:id="@id/coffeeGraph"
   android:icon="@drawable/coffee_cup"
   android:title="@string/coffee_name" />

这里我更新了菜单以使用引用图的 id。由于 CoffeeList 是所引用图的起始页面,所以我可以使用图 id 来导航到这个图。如果您现在试着运行应用,所有的功能会和之前一样。

现在咖啡记录的导航图已经实现分离,我们可以对应用进行模块化处理,顺便可以看一下在模块之间导航的效果如何。

如果您希望同步操作,可以检查 代码,里面包含了到目前为止我所做的全部修改。我创建了两个新的模块: core 和 coffee。我将所有常用的类迁移到 core 模块中,比如 Donut、Coffee、DAO、Database 以及其他常见资源。

接下来,我将所有在咖啡记录中用到的 fragment、viewModel 和 adapter 类迁移到 coffee 模块中。在咖啡记录中用到的布局和其他资源也迁移到这里,包括 coffee_graph。

如果你想了解更多关于前后端的技术内容,可以通过技术开发平台:厦门在乎科技-专注小程序开发、厦门app开发公司、网站开发

相关文章
|
3月前
|
移动开发 前端开发 JavaScript
Twaver-HTML5基础学习(13)连线(Link)连线的绑定与展开
本文介绍了Twaver HTML5中连线(Link)的绑定与展开功能,包括分组绑定、自环绑定、绑定与展开以及展开间隙等属性的设置。通过示例代码展示了如何在React组件中创建Link并设置其绑定属性,实现连线的分组管理。
33 4
Twaver-HTML5基础学习(13)连线(Link)连线的绑定与展开
|
自然语言处理
【Qt编程】基于Qt的词典开发系列&lt;十一&gt;系统托盘的显示
    本文主要讨论Qt中的系统托盘的设置。系统托盘想必大家都不陌生,最常用的就是QQ。系统托盘以简单、小巧的形式能让人们较快的打开软件。废话不多说,下面开始具体介绍。
1303 0
|
Android开发 索引 iOS开发
第二十四章:页面导航(十七)
像现实生活中的应用程序理想情况下,用户在终止并重新启动应用程序时不应该知道。应用程序体验应该是连续且无缝的。即使程序没有一直运行,一个半月进入的条目从未完成也应该在一周后处于相同的状态。NoteTaker程序允许用户记录由标题和一些文本组成的注释。
548 0
|
XML JSON Android开发
第二十四章:页面导航(十五)
保存和恢复页面状态特别是当您开始使用多页面应用程序时,将应用程序的页面视为数据的主要存储库非常有用,而仅仅是作为底层数据的临时可视化和交互式视图。这里的关键词是暂时的。如果您在用户与之交互时保持基础数据是最新的,那么页面可以显示和消失而不必担心。
656 0
|
JavaScript Android开发
第二十四章:页面导航(十四)
切换到ViewModel此时应该很明显,Information类应该真正实现INotifyPropertyChanged。 在DataTransfer5中,Information类已成为InformationViewModel类。
605 0
|
Android开发 索引
第二十四章:页面导航(十一)
消息中心您可能不喜欢两个页面类直接相互调用方法的想法。 它似乎适用于小样本,但对于具有大量类间通信的大型程序,您可能更喜欢一些不需要实际页面实例的更灵活的东西。这样的工具是Xamarin.Forms MessagingCenter类。
557 0
|
JavaScript Android开发 索引
第二十四章:页面导航(十)
属性和方法调用调用PushAsync或PushModalAsync的页面显然可以直接访问它导航到的类,因此它可以设置属性或调用该页面对象中的方法以将信息传递给它。但是,调用PopAsync或PopModalAsync的页面还有一些工作要做,以确定它返回的页面。
554 0
|
JavaScript Android开发
第二十四章:页面导航(九)
数据传输模式 多页面应用程序中的页面通常需要共享数据,特别是一页面将信息传递到另一页面。 有时此过程类似于函数调用:当HomePage显示项目列表并导航到DetailPage以显示其中一个项目的详细视图时,HomePage必须将该特定项目传递给DetailPage。
634 0
|
Android开发
第二十四章:页面导航(八)
动态页面生成BuildAPage程序是一个多页面应用程序,但BuildAPage项目只包含一个名为BuildAPageHomePage的页面类。 顾名思义,该程序从代码构造一个新页面,然后导航到它。XAML文件允许您在此构造的页面上指定所需内容: <ContentPage xmlns="http://xamarin.
673 0
|
JavaScript Go Android开发
第二十四章:页面导航(七)
操纵导航堆栈有时需要改变正常的面向堆栈的导航流程。例如,假设页面需要来自用户的一些信息,但首先它导航到提供一些指令或免责声明的页面,然后从那里导航到实际获取信息的页面。当用户完成并返回时,您将希望跳过包含说明或免责声明的页面。
661 0