头图

This is the second MAD Skills series about navigation. This article is the third article in the navigation component series. If you want to review the content published in the past, please refer to the link below to view:

If you prefer to watch video rather than reading the article, please click here to view video content.

Overview

In the previous articles in this series, we added the coffee record function, used the navigation UI to improve the user experience, and implemented conditional navigation.

In this article, we will learn how to manage navigation graphs by using nested graphs, and use the include tag to introduce other graphs. This requires us to modularize the application and understand how navigation is implemented between modules.

So, next, let us open Android Studio and start learning how to use navigation on the module.

Nested Navigation Map

We start with the navigation map. Nested graphs allow you to group a series of destination pages in the parent navigation graph.

Let's take a look at the navigation map. The coffeeList and coffeeEntryDialog destination pages are very suitable for conversion to nested maps. To achieve this, I long press shift and select "Move to Nested Graph" at the same time:

△ 将 coffeeList 和 coffeeEntryDialogFragment 移动到嵌套图

△ Move coffeeList and coffeeEntryDialogFragment to nested graph

Now we return to the code interface, you can see that the nested graph is just a new navigation graph in the root 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"
   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>

The navigation between the selected fragments is migrated to the nested graph.

Nested graphs must contain id. You can use this id to implement the code that navigates to the nested graph, but it is not directly converted to its sub-destination page. Nested graphs contain their own start destination pages, and please do not expose their sub-destination pages separately.

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

If you double-click the nested graph, you can find the nested destination pages and the operations between them.

Include Tag

In addition to using nested graphs, I can also extract graphs into a new navigation xml file. I created a new xml file here, named coffee_graph, and migrated the content of the nested graph to this file.

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

I can nest the new graph into other files through the include tag. Although using the include tag is functionally the same as using nested diagrams, you can also use diagrams from other project modules or library projects.

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

Similar to the nested graph, the referenced graph does not expose the list of destination pages, which means I need to update the menu id to point to the coffeeList.

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

Here I updated the menu to use the id of the reference image. Since CoffeeList is the starting page of the referenced graph, I can use the graph id to navigate to this graph. If you try to run the application now, all functions will be the same as before.

Now that the navigation map of the coffee record has been separated, we can modularize the application. By the way, we can see how the navigation between modules is effective.

If you want to operate synchronously, you can check the code , which contains all the changes I have made so far. I created two new modules: core and coffee. I migrated all the commonly used classes to the core module, such as Donut, Coffee, DAO, Database, and other common resources.

Next, I migrated all the fragment, viewModel, and adapter classes used in coffee records to the coffee module. The layout and other resources used in coffee records are also migrated here, including coffee_graph.

△ 已有的类和资源被迁移到了 core 和 coffee 模块中

△ Existing classes and resources have been migrated to core and coffee modules

The coffee module depends on the core module:

dependencies {

   implementation project(":core")

   //...
}

Finally, in the app module, add coffee and core as dependencies of the app module:

dependencies {
   implementation project(":coffee")
   implementation project(":core")
   //..
}

Please note that there is no change in the navigation chart here, and it is not affected by these changes:

△ 导航图没有发生变化

△ The navigation map has not changed

Now if you run the application, all functions are the same as usual, except that the module is used internally. You can view final code .

Through the above modification, I separated the coffee recording module and its related navigation flow from the application, which means that the coffee recording module can be used independently of the doughnut recording application.

summary

In this article, we learned how to create a nested navigation map and how to use the include tag to modularize the donut recording application.

In the next article, we will further learn how to use functional modules for navigation. stay tuned!

Welcome to Click here to submit feedback to us, or share your favorite content or problems found. Your feedback is very important to us, thank you for your support!


Android开发者
404 声望2k 粉丝

Android 最新开发技术更新,包括 Kotlin、Android Studio、Jetpack 和 Android 最新系统技术特性分享。更多内容,请关注 官方 Android 开发者文档。