嵌套导航图

您可以将一系列目的地归入父级导航图(称为“根图”)内的一个嵌套图中。嵌套图对于整理和重复使用应用界面的各个部分(例如独立的登录流程)非常有用。

嵌套图可以封装其目的地。与根图一样,嵌套图必须具有标识为起始目的地的目的地。嵌套图之外的目的地(例如根图上的目的地)只能通过其起始目的地访问嵌套图。

图 1 显示了一个简单的转帐应用的导航图。从左侧的起始目的地中,该图分出两个流程:一个位于顶部,用于汇款;另一个位于底部,用于查看帐号余额。

图 1. 转帐导航图

如需将目的地归入一个嵌套图中,请执行以下操作:

  1. 在 Navigation Editor 中,按住 Shift 键,然后点击您想要添加到嵌套图中的目的地。
  2. 右键点击以打开上下文菜单,然后依次选择 Move to Nested Graph > New Graph。目的地包含在嵌套图中。图 2 显示了 Navigation Editor 中的嵌套图:

    图 2. Graph Editor 中的嵌套图
  3. 点击嵌套图。此时 Attributes 面板中会显示以下属性:

    • Type,其中包含“Nested Graph”
    • ID,其中包含系统为嵌套图分配的 ID。此 ID 用于从代码中引用嵌套图。
  4. 双击嵌套图以显示其目的地。

  5. 点击 Text 标签页,以切换到 XML 视图。一个嵌套导航图已添加到该图中。此导航图具有自己的 navigation 元素,以及自己的 ID 和一个指向嵌套图中第一个目的地的 startDestination 属性:

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:android="http://schemas.android.com/apk/res/android"
        app:startDestination="@id/mainFragment">
        <fragment
            android:id="@+id/mainFragment"
            android:name="com.example.cashdog.cashdog.MainFragment"
            android:label="fragment_main"
            tools:layout="@layout/fragment_main" >
            <action
                android:id="@+id/action_mainFragment_to_sendMoneyGraph"
                app:destination="@id/sendMoneyGraph" />
            <action
                android:id="@+id/action_mainFragment_to_viewBalanceFragment"
                app:destination="@id/viewBalanceFragment" />
        </fragment>
        <fragment
            android:id="@+id/viewBalanceFragment"
            android:name="com.example.cashdog.cashdog.ViewBalanceFragment"
            android:label="fragment_view_balance"
            tools:layout="@layout/fragment_view_balance" />
        <navigation android:id="@+id/sendMoneyGraph" app:startDestination="@id/chooseRecipient">
            <fragment
                android:id="@+id/chooseRecipient"
                android:name="com.example.cashdog.cashdog.ChooseRecipient"
                android:label="fragment_choose_recipient"
                tools:layout="@layout/fragment_choose_recipient">
                <action
                    android:id="@+id/action_chooseRecipient_to_chooseAmountFragment"
                    app:destination="@id/chooseAmountFragment" />
            </fragment>
            <fragment
                android:id="@+id/chooseAmountFragment"
                android:name="com.example.cashdog.cashdog.ChooseAmountFragment"
                android:label="fragment_choose_amount"
                tools:layout="@layout/fragment_choose_amount" />
        </navigation>
    </navigation>
    
  6. 在代码中,传递将根图连接到嵌套图的操作的资源 ID:

    Kotlin

    view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)
    

    Java

    Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
    

  7. 返回 Design 标签页,您可以通过点击 Root 返回到根图。

通过 <include> 引用其他导航图

在导航图中,您可以使用 include 引用其他图。虽然这在功能上与使用嵌套图相同,但 include 可让您使用其他项目模块或库项目中的图,如以下示例所示:

<!-- (root) nav_graph.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/fragment">

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

    <fragment
        android:id="@+id/fragment"
        android:name="com.example.myapplication.BlankFragment"
        android:label="Fragment in Root Graph"
        tools:layout="@layout/fragment_blank">
        <action
            android:id="@+id/action_fragment_to_second_graph"
            app:destination="@id/second_graph" />
    </fragment>

    ...
</navigation>
<!-- included_graph.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/second_graph"
    app:startDestination="@id/includedStart">

    <fragment
        android:id="@+id/includedStart"
        android:name="com.example.myapplication.IncludedStart"
        android:label="fragment_included_start"
        tools:layout="@layout/fragment_included_start" />
</navigation>

其他资源

如需详细了解 Navigation,请参阅下面列出的其他资源:

示例

Codelab

视频