本主题介绍了如何设置和使用 Navigation 组件。如需简要了解 Navigation 组件,请参阅导航概览。
设置您的环境
如需在您的项目中添加 Navigation 支持,请向应用的 build.gradle
文件添加以下依赖项:
Groovy
dependencies { def nav_version = "2.5.3" // Java language implementation implementation "androidx.navigation:navigation-fragment:$nav_version" implementation "androidx.navigation:navigation-ui:$nav_version" // Kotlin implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version" // Feature module Support implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version" // Testing Navigation androidTestImplementation "androidx.navigation:navigation-testing:$nav_version" // Jetpack Compose Integration implementation "androidx.navigation:navigation-compose:$nav_version" }
Kotlin
dependencies { val nav_version = "2.5.3" // Java language implementation implementation("androidx.navigation:navigation-fragment:$nav_version") implementation("androidx.navigation:navigation-ui:$nav_version") // Kotlin implementation("androidx.navigation:navigation-fragment-ktx:$nav_version") implementation("androidx.navigation:navigation-ui-ktx:$nav_version") // Feature module Support implementation("androidx.navigation:navigation-dynamic-features-fragment:$nav_version") // Testing Navigation androidTestImplementation("androidx.navigation:navigation-testing:$nav_version") // Jetpack Compose Integration implementation("androidx.navigation:navigation-compose:$nav_version") }
如需了解如何向您的项目添加其他架构组件,请参阅向项目添加组件。
创建导航图
导航发生在应用中的各个目的地(即您的应用中用户可以导航到的任意位置)之间。这些目的地是通过操作连接的。
导航图是一种资源文件,其中包含您的所有目的地和操作。该图表会显示应用的所有导航路径。
图 1 直观显示了一个示例应用的导航图,该应用包含 6 个目的地(通过 5 个操作连接)。每个目的地均由一个预览缩略图表示,连接操作由箭头表示,该箭头表示用户可以如何从一个目的地导航到另一个目的地。

- “目的地”是指应用中的不同内容区域。
- “操作”是指目的地之间的逻辑连接,表示用户可以采取的路径。
如需向项目添加导航图,请执行以下操作:
- 在“Project”窗口中,右键点击
res
目录,然后依次选择 New > Android Resource File。此时系统会显示 New Resource File 对话框。 - 在 File name 字段中输入名称,例如“nav_graph”。
- 从 Resource type 下拉列表中选择 Navigation,然后点击 OK。
当您添加首个导航图时,Android Studio 会在 res
目录内创建一个 navigation
资源目录。该目录包含您的导航图资源文件(例如 nav_graph.xml
)。
Navigation Editor
添加图表后,Android Studio 会在 Navigation Editor 中打开该图表。在 Navigation Editor 中,您可以直观地修改导航图,或直接修改底层 XML。

- Destinations panel:列出了导航宿主和目前位于 Graph Editor 中的所有目的地。
- Graph Editor:包含导航图的视觉表示形式。您可以在 Design 视图和 Text 视图中的底层 XML 表示形式之间切换。
- Attributes:显示导航图中当前所选项的属性。
点击 Text 标签页可查看相应的 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"
android:id="@+id/nav_graph">
</navigation>
<navigation>
元素是导航图的根元素。当您向图表添加目的地和连接操作时,可以看到相应的 <destination>
和 <action>
元素在此处显示为子元素。如果您有嵌套图表,它们将显示为子 <navigation>
元素。
向 Activity 添加 NavHost
导航宿主是 Navigation 组件的核心部分之一。导航宿主是一个空容器,用户在您的应用中导航时,目的地会在该容器中交换进出。
导航宿主必须派生于 NavHost
。Navigation 组件的默认 NavHost
实现 (NavHostFragment
) 负责处理 fragment 目的地的交换。
通过 XML 添加 NavHostFragment
以下 XML 示例显示了作为应用主 Activity 一部分的 NavHostFragment
:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.appcompat.widget.Toolbar .../> <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph" /> <com.google.android.material.bottomnavigation.BottomNavigationView .../> </androidx.constraintlayout.widget.ConstraintLayout>
请注意以下几点:
android:name
属性包含NavHost
实现的类名称。app:navGraph
属性将NavHostFragment
与导航图相关联。导航图会在此NavHostFragment
中指定用户可以导航到的所有目的地。app:defaultNavHost="true"
属性确保您的NavHostFragment
会拦截系统返回按钮。请注意,只能有一个默认NavHost
。如果同一布局(例如,双窗格布局)中有多个宿主,请务必仅指定一个默认NavHost
。
您也可以使用布局编辑器向 activity 添加 NavHostFragment
,具体操作步骤如下:
- 在项目文件列表中,双击 Activity 的布局 XML 文件,以在 Layout Editor 中将其打开。
- 在 Palette 窗格内,选择 Containers 类别,或者搜索“NavHostFragment”。
- 将
NavHostFragment
视图拖动到您的 Activity 上。 - 接下来,在随即显示的 Navigation Graphs 对话框中,选择需要与此
NavHostFragment
相关联的相应导航图,然后点击 OK。
向导航图添加目的地
您可以从现有的 Fragment 或 Activity 创建目的地。您还可以使用 Navigation Editor 创建新目的地,或创建占位符以便稍后替换为 fragment 或 activity。
在本示例中,我们来创建一个新目的地。如需使用 Navigation Editor 添加新目的地,请执行以下操作:
- 在 Navigation Editor 中,点击 New Destination 图标
,然后点击 Create new destination。
- 在随即显示的 New Android Component 对话框中,创建您的 Fragment。如需详细了解 Fragment,请参阅 Fragment 文档。
当您返回到 Navigation Editor 中时,会发现 Android Studio 已将此目的地添加到图中。
图 1 显示了目的地和占位符目的地的示例。

如需了解向导航图添加目的地的其他方式,请参阅创建目的地。
目的地详解
点击一个目的地以将其选中,并注意 Attributes 面板中显示的以下属性:
- Type 字段指示在您的源代码中,该目的地是作为 fragment、activity 还是其他自定义类实现的。
- Label 字段包含该目的地的用户可读名称。例如,如果您使用
setupWithNavController()
将NavGraph
连接到Toolbar
,就可能在界面上看到此字段。因此,我们建议您对此值使用资源字符串。 - ID 字段包含该目的地的 ID,它用于在代码中引用该目的地。
- Class 下拉列表显示与该目的地相关联的类的名称。您可以点击此下拉列表,将相关联的类更改为其他目的地类型。
点击 Text 标签页可查看导航图的 XML 视图。XML 中同样包含该目的地的 id
、name
、label
和 layout
属性,如下所示:
<?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/blankFragment"> <fragment android:id="@+id/blankFragment" android:name="com.example.cashdog.cashdog.BlankFragment" android:label="@string/label_blank" tools:layout="@layout/fragment_blank" /> </navigation>
将某个屏幕指定为起始目的地
起始目的地是用户打开您的应用时看到的第一个屏幕,也是用户退出您的应用时看到的最后一个屏幕。Navigation Editor 使用房子图标 表示起始目的地。
所有目的地就绪后,您便可以选择起始目的地,具体操作步骤如下:
在 Design 标签页中,点击相应目的地,使其突出显示。
点击 Assign start destination 按钮
。或者,您可以右键点击该目的地,然后点击 Set as Start Destination。
连接目的地
操作是指目的地之间的逻辑连接。操作在导航图中以箭头表示。操作通常会将一个目的地连接到另一个目的地,不过您也可以创建全局操作,此类操作可让您从应用中的任意位置转到特定目的地。
借助操作,您可以表示用户在您的应用中导航时可以采取的不同路径。请注意,如需实际导航到各个目的地,您仍然需要编写代码以执行导航操作。如需了解详情,请参阅本主题后面的导航到目的地部分。
您可以使用 Navigation Editor 将两个目的地连接起来,具体操作步骤如下:
在 Design 标签页中,将鼠标悬停在目的地的右侧,该目的地为您希望用户从中导航出来的目的地。该目的地右侧上方会显示一个圆圈,如图 4 所示。
图 4. 一个包含操作连接圆圈的目的地 点击您希望用户导航到的目的地,并将光标拖动到该目的地的上方,然后松开。这两个目的地之间生成的线条表示操作,如图 5 所示。
图 5. 通过操作连接目的地 点击箭头以突出显示该操作。此时 Attributes 面板中会显示以下属性:
- Type 字段包含“Action”。
- ID 字段包含该操作的 ID。
- Destination 字段包含目的地 Fragment 或 Activity 的 ID。
点击 Text 标签,以切换到 XML 视图。现在,一个 action 元素已添加到源目的地中。该操作有一个 ID 和一个目的地属性(其中包含下一个目的地的 ID),如以下示例所示:
<?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/blankFragment"> <fragment android:id="@+id/blankFragment" android:name="com.example.cashdog.cashdog.BlankFragment" android:label="@string/label_blank" tools:layout="@layout/fragment_blank" > <action android:id="@+id/action_blankFragment_to_blankFragment2" app:destination="@id/blankFragment2" /> </fragment> <fragment android:id="@+id/blankFragment2" android:name="com.example.cashdog.cashdog.BlankFragment2" android:label="@string/label_blank_2" tools:layout="@layout/fragment_blank_fragment2" /> </navigation>
在导航图中,操作由 <action>
元素表示。操作至少应包含自己的 ID 和用户应转到的目的地的 ID。
导航到目的地
导航到目的地是使用 NavController
完成的,它是一个在 NavHost
中管理应用导航的对象。每个 NavHost
均有自己的相应 NavController
。您可以使用以下方法之一检索 NavController
:
Kotlin:
Java:
NavHostFragment.findNavController(Fragment)
Navigation.findNavController(Activity, @IdRes int viewId)
Navigation.findNavController(View)
使用 FragmentContainerView
创建 NavHostFragment
,或通过 FragmentTransaction
手动将 NavHostFragment
添加到您的 Activity 时,尝试通过 Navigation.findNavController(Activity, @IdRes int)
检索 Activity 的 onCreate()
中的 NavController
将失败。您应改为直接从 NavHostFragment
检索 NavController
。
Kotlin
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController
Java
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController();
使用 Safe Args 确保类型安全
如需在目的地之间导航,建议使用 Safe Args Gradle 插件。该插件可以生成简单的对象和构建器类,这些类支持在目的地之间进行类型安全的导航和参数传递。
如需将 Safe Args 添加到您的项目,请在顶层 build.gradle
文件中包含以下 classpath
:
Groovy
buildscript { repositories { google() } dependencies { def nav_version = "2.5.3" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" } }
Kotlin
buildscript { repositories { google() } dependencies { val nav_version = "2.5.3" classpath("androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version") } }
您还必须应用以下两个可用插件之一。
如需生成适用于 Java 模块或 Java 和 Kotlin 混合模块的 Java 语言代码,请将以下行添加到应用或模块的 build.gradle
文件中:
Groovy
plugins { id 'androidx.navigation.safeargs' }
Kotlin
plugins { id("androidx.navigation.safeargs") }
此外,如需生成仅适用于 Kotlin 模块的 Kotlin 语言代码,请添加以下行:
Groovy
plugins { id 'androidx.navigation.safeargs.kotlin' }
Kotlin
plugins { id("androidx.navigation.safeargs.kotlin") }
根据迁移到 AndroidX 文档,您的 gradle.properties
文件中必须具有 android.useAndroidX=true
。
启用 Safe Args 后,该插件会生成代码,其中包含您定义的每个操作的类和方法。对于每个操作,Safe Args 还会为每个源目的地(生成相应操作的目的地)生成一个类。生成的类的名称由源目的地类的名称和“Directions”一词组成。例如,如果目的地的名称为 SpecifyAmountFragment
,生成的类的名称为 SpecifyAmountFragmentDirections
。生成的类为源目的地中定义的每个操作提供了一个静态方法。该方法会将任何定义的操作参数作为参数,并返回可传递到 navigate()
的 NavDirections
对象。
例如,假设我们的导航图包含一个操作,该操作将源目的地 SpecifyAmountFragment
和接收目的地 ConfirmationFragment
连接起来。
Safe Args 会生成一个 SpecifyAmountFragmentDirections
类,其中只包含一个 actionSpecifyAmountFragmentToConfirmationFragment()
方法(该方法会返回 NavDirections
对象)。然后,您可以将返回的 NavDirections
对象直接传递到 navigate()
,如以下示例所示:
Kotlin
override fun onClick(view: View) { val action = SpecifyAmountFragmentDirections .actionSpecifyAmountFragmentToConfirmationFragment() view.findNavController().navigate(action) }
Java
@Override public void onClick(View view) { NavDirections action = SpecifyAmountFragmentDirections .actionSpecifyAmountFragmentToConfirmationFragment(); Navigation.findNavController(view).navigate(action); }
如需详细了解如何使用 Safe Args 在目的地之间传递数据,请参阅使用 Safe Args 传递类型安全的数据。
更多信息
- 导航概览
- 创建目的地
- 导航到目的地
- 使用 NavigationUI 更新界面组件
- 在目的地之间传递数据
- 全局操作
- 条件目的地
- 自定义目的地类型
- Android Jetpack:使用导航控制器管理界面导航(2018 年 Google I/O 大会)
- 将现有项目迁移至导航架构组件
- Navigation Codelab
如果您遇到任何与 Navigation 相关的问题,请通过以下渠道之一提交反馈:
如需了解如何在错误报告中提供最有用的信息,请访问以下链接: