Navigation 组件使用导航图管理应用导航。导航图是一种资源文件,其中包含应用的所有目的地和逻辑连接(后者也称为“操作”,用户可以通过执行这些操作从一个目的地导航到另一个目的地)。您可以使用 Android Studio 中的 Navigation Editor 管理应用的导航图。
本主题包含有关设计应用导航图的最佳做法和建议。
顶级导航图
应用的顶级导航图应从用户启动应用时看到的初始目的地开始,且应包含他们在应用中四处浏览时看到的目的地。
图 1. 顶级导航图。
嵌套图
应用中的登录流程、向导或其他子流程通常是嵌套导航图的最佳表示形式。通过以这种方式嵌套独立的子导航流程,您可以更轻松地理解和管理应用界面的主流程。此外,嵌套图表可以重复使用。嵌套图表还提供一定程度的封装,即嵌套图表之外的目的地无法直接访问嵌套图表内的任何目的地。相反,这些目的地应 navigate()
到嵌套图表本身,在嵌套图表中,内部逻辑可以发生更改,而不会影响图表的其余部分。
以图 1 中的顶级导航图为例,假设您希望仅在用户首次启动应用时让其看到 title_screen 和 register 屏幕。之后,系统会存储用户信息。用户以后启动应用时,您应直接将其转到 match 屏幕。最佳实践应该是将 match 屏幕设置为顶级导航图的起始目的地,并将标题屏幕和注册屏幕移至嵌套图表中,如图 2 所示:
图 2. 顶级导航图现在包含一个嵌套图。
match 屏幕启动后,您可以检查是否有注册用户。如果用户未注册,您可以将其转到注册屏幕。如需详细了解条件导航情形,请参阅条件导航。
将图结构模块化的另一种方法是,通过父级导航图中的 <include>
元素,将一个图包含在另一个图中。这样一来,就可以完全在单独的模块或项目中定义包含的图,从而最大限度提高可重用性。
在库模块中导航
如果您的应用依赖包含导航图的库模块,您可以使用 <include>
元素引用这些导航图。
如需了解详情,请参阅多模块项目的导航最佳做法。
全局操作
对于应用中的任何可通过多条路径到达的目的地,都应定义一项可导航到该目的地的相应全局操作。全局操作可用于从任意位置导航到某目的地。
下面我们将全局操作应用于库模块示例,该示例在获胜目的地和游戏结束目的地中定义了同一操作。您应将这些常见操作提取到一个全局操作,并从这两个目的地引用相应操作,如以下示例所示:
<?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"
android:id="@+id/in_game_nav_graph"
app:startDestination="@id/in_game">
<!-- Action back to destination which launched into this in_game_nav_graph-->
<action android:id="@+id/action_pop_out_of_game"
app:popUpTo="@id/in_game_nav_graph"
app:popUpToInclusive="true" />
<fragment
android:id="@+id/in_game"
android:name="com.example.android.gamemodule.InGame"
android:label="Game">
<action
android:id="@+id/action_in_game_to_resultsWinner"
app:destination="@id/results_winner" />
<action
android:id="@+id/action_in_game_to_gameOver"
app:destination="@id/game_over" />
</fragment>
<fragment
android:id="@+id/results_winner"
android:name="com.example.android.gamemodule.ResultsWinner" />
<fragment
android:id="@+id/game_over"
android:name="com.example.android.gamemodule.GameOver"
android:label="fragment_game_over"
tools:layout="@layout/fragment_game_over" />
</navigation>
如需了解详情以及查看如何在 Fragment 中使用全局操作的示例,请参阅导航文档中的全局操作。