Navigation Component — Android Jetpack 库,用于实现应用程序屏幕之间的导航。该组件集中管理片段堆栈、深层链接和参数传递。自 2018 年起成为 Jetpack 的一部分,并被 Google 推荐用于所有新项目。更多信息请阅读 Google 官方指南。
要点
Navigation Component — Android Jetpack 库 (androidx.navigation),提供统一的导航 API。包含三个关键元素:Navigation Graph(导航图)、NavHostFragment(屏幕容器)和 NavController(过渡控制器)。该组件自动管理返回堆栈并支持深层链接。
在 Navigation Component 之前,开发人员通过 FragmentManager 手动管理片段。这导致代码碎片化:每个屏幕有自己的导航规则,返回堆栈状态不同,深层链接需要单独实现。Navigation Component 统一了这些场景。根据 Google 的数据(2026),该库已安装在 90% 的新 Android 项目中。
Navigation Component 与其他 Jetpack 库集成:LiveData、ViewModel、Material Design。支持 XML 片段和通过 navigation-compose 扩展的 Jetpack Compose。稳定版本 — 2.8.x(2025),最低 Android 版本 — API 14。
NavGraph — XML 资源 (res/navigation/nav_graph.xml),定义应用程序的所有屏幕及其之间的连接。每个屏幕是一个节点(destination),可以是 Fragment、Activity 或 Composable。节点之间的连接称为 action,指定过渡方向。
<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/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name=".HomeFragment"
android:label="首页"
tools:layout="@layout/fragment_home">
<action
android:id="@+id/action_home_to_detail"
app:destination="@+id/detailFragment"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
</fragment>
<fragment
android:id="@+id/detailFragment"
android:name=".DetailFragment"
android:label="详情"
tools:layout="@layout/fragment_detail">
<argument android:name="itemId"
app:argType="integer"
android:defaultValue="0" />
</fragment>
</navigation>startDestination 属性设置启动时显示的第一个屏幕。Action 定义目标 destination 和可选的动画。参数(argument)描述传递到屏幕的参数 — 类型和默认值。
NavHostFragment — 放置在 Activity 布局中并显示当前导航屏幕的容器。NavHostFragment 在调用 NavController.navigate() 时自动切换片段。NavController — 管理导航的对象:过渡、返回、检查当前路由。
// Layout Activity: activity_main.xml
// <androidx.fragment.app.FragmentContainerView
// android:id="@+id/nav_host_fragment"
// android:name="androidx.navigation.fragment.NavHostFragment"
// app:navGraph="@navigation/nav_graph"
// app:defaultNavHost="true" />
class MainActivity : AppCompatActivity() {
private val navController by lazy {
(findViewById<NavHostFragment>(R.id.nav_host_fragment))
.navController
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// NavigationUI 将 NavController 与 AppBar 连接
setupActionBarWithNavController(navController)
}
// 切换到详情屏幕
fun openDetail(itemId: Long) {
val bundle = Bundle().apply {
putLong("itemId", itemId)
}
navController.navigate(R.id.action_home_to_detail, bundle)
}
override fun onSupportNavigateUp() =
navController.navigateUp() || super.onSupportNavigateUp()
}app:defaultNavHost="true" — 重要属性:拦截系统「返回」按钮并将控制权交给 NavController。NavigationUI — 用于将 NavController 连接到 AppBar、BottomNavigationView、NavigationDrawer 的实用工具。setupActionBarWithNavController 在嵌套屏幕上启用「向上」箭头。
Navigation Component 支持自定义过渡动画,在 action 中或通过编程定义。动画由四个属性定义:enterAnim(新屏幕出现)、exitAnim(当前屏幕消失)、popEnterAnim(返回时出现)和 popExitAnim(返回时消失)。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="100%"
android:toXDelta="0%"
android:duration="300" />
</set>
// 带动画的编程过渡
val navOptions = NavOptions.Builder()
.setEnterAnim(R.anim.slide_in_right)
.setExitAnim(R.anim.slide_out_left)
.setPopEnterAnim(R.anim.slide_in_left)
.setPopExitAnim(R.anim.slide_out_right)
.build()
navController.navigate(R.id.detailFragment, args, navOptions)动画在 FragmentTransaction 级别与 Fragment 一起工作。对于 Jetpack Compose,动画通过 NavOptionsCompat 使用 Compose Animation 设置。Navigation Component 不限制动画类型 — 支持 translate、scale、alpha 及其组合。
Safe Args — Gradle 插件,用于屏幕之间类型安全的数据传输。插件分析 NavGraph,生成具有特定类型字段的 Directions 和 Args 类。在编译阶段检查类型匹配 — MissingArgumentException 错误在应用程序启动前被检测到。
// build.gradle (module)
plugins {
id 'androidx.navigation.safeargs.kotlin'
}
// Safe Args 生成:DetailFragmentArgs、HomeFragmentDirections
// 在 HomeFragment 中使用:
val action = HomeFragmentDirections
.actionHomeToDetail(itemId = 42L)
findNavController().navigate(action)
// 在 DetailFragment 中使用:
private val args: DetailFragmentArgs by navArgs()
// args.itemId 类型为 Long,不能传递 null
override fun onViewCreated(...) {
super.onViewCreated(...)
loadItem(args.itemId)
}navArgs() — Kotlin 委托,用于在 Fragment 或 Activity 中获取参数。插件支持原始类型、字符串、Parcelable、Serializable、Enum 和数组。对于复杂对象,使用 ID 传递并从 ViewModel 或数据库加载。
Deep Link — 打开应用程序特定屏幕的外部链接。Navigation Component 通过 NavGraph 中的 app:deepLink 属性处理深层链接。系统创建一个 PendingIntent,将导航堆栈恢复到目标屏幕,如果应用程序未运行则创建新堆栈。
<fragment android:id="@+id/profileFragment"
android:name=".ProfileFragment">
<deepLink
app:uri="https://example.com/profile/{userId}" />
<argument
android:name="userId"
app:argType="string" />
</fragment>
// 编程创建 Deep Link
val pendingIntent = NavDeepLinkBuilder(context)
.setGraph(R.navigation.nav_graph)
.setDestination(R.id.profileFragment)
.setArguments(Bundle().apply {
putString("userId", "user_123")
})
.createPendingIntent()深层链接支持带有路径和查询参数的 URI 模板、intent action 和 mime type。占位符 ({userId}) 自动映射到 destination 参数。Navigation Component 还通过 AndroidManifest 处理隐式深层链接 — 只需向带有 NavHostFragment 的 Activity 添加 intent-filter 即可。
Navigation Compose (androidx.navigation:navigation-compose) — Navigation Component 对 Jetpack Compose 的扩展。API 保留了 NavController 和 NavHost 的概念,但屏幕是 Composable 函数而非 Fragment。NavHost 为每个路由接收 composable lambda。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyAppTheme {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = "home"
) {
composable("home") {
HomeScreen(
onItemClick = { id ->
navController.navigate("detail/$id")
}
)
}
composable(
route = "detail/{itemId}",
arguments = listOf(
navArgument("itemId") {
type = NavType.LongType
}
)
) { backStackEntry ->
val itemId = backStackEntry
.arguments?.getLong("itemId") ?: 0L
DetailScreen(itemId = itemId)
}
}
}
}
}
}Navigation Compose 使用字符串路由而不是 id。参数通过路由模板 ("detail/{itemId}") 传递并从 backStackEntry 中提取。rememberNavController() 在重组时保留 NavController。对于 Compose 中的 Type Safety,推荐使用 navigation-compose-type-safety 模块(实验性)。
常见问题
NavHost — 用于显示导航屏幕的容器。通过 XML 布局中的 NavHostFragment 实现。NavHost 跟踪 NavGraph 中的当前屏幕并管理过渡。每个 Activity 包含一个 NavHostFragment。
Safe Args — Gradle 插件,生成类型安全的参数类。Bundle 需要手动指定键和类型,导致运行时错误。Safe Args 在编译阶段检查类型并自动序列化数据。
复杂对象通过 ViewModel(屏幕之间共享)或通过数据库传递 ID 来传递。Safe Args 只支持原始类型、字符串和 Parcelable。Google 建议避免通过导航参数传递大型对象。
Deep Link 在 NavGraph 中通过 app:deepLink 属性配置。Navigation Component 自动处理传入的链接,通过 NavDeepLinkBuilder 创建 PendingIntent,并将导航堆栈恢复到目标屏幕。支持 URI、intent action 和 mime type。
可以。Navigation Compose (androidx.navigation:navigation-compose) 为 Compose 提供 NavHost。API 类似于 XML 版本,但屏幕是 Composable 函数。NavController 在两个版本中使用方式相同。Google 推荐在 Compose 新项目中使用 Navigation Compose。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。