news 2026/1/13 19:37:55

Jetpack Compose Navigation 全面使用指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Jetpack Compose Navigation 全面使用指南

🧭 一、为什么需要 Navigation?

在 Compose 中,你不再用Activity 跳转,而是用“声明式导航”

  • 页面 =Composable 函数
  • 跳转 =改变当前“目的地”(Destination)
  • 返回 =从导航栈弹出

Jetpack Compose Navigation 提供了一套统一、安全、带生命周期管理的导航方案。

🛠 二、快速上手:3 步实现页面跳转

第 1 步:添加依赖(build.gradle)

implementation"androidx.navigation:navigation-compose:2.8.0"

第 2 步:定义你的页面(Composable)

@ComposablefunHomeScreen(onNavigateToProfile:()->Unit){Column{Text("首页")Button(onClick=onNavigateToProfile){Text("去个人页")}}}@ComposablefunProfileScreen(){Text("个人中心")}

第 3 步:搭建导航图(NavGraph)

@ComposablefunMyApp(){valnavController=rememberNavController()NavHost(navController=navController,startDestination="home"){composable("home"){HomeScreen{navController.navigate("profile")}}composable("profile"){ProfileScreen()}}}

✅ 效果:点击按钮 → 跳转到个人页!

✅ 返回键自动生效(因为 NavHost 管理了返回栈)

🔑 三、核心概念解析

概念说明
NavController导航控制器,负责跳转、返回等操作
NavHost导航容器,定义所有页面(目的地)
composable(route)声明一个页面,route 是唯一标识(如 “profile”)
导航栈(Back Stack)记录用户访问路径,支持返回

💡 记住:

  • rememberNavController():在 Composable 中获取 NavController
  • 每个 composable 块对应一个页面

📦 四、页面传参(Arguments)

场景:从首页跳转到用户详情页,传userId

✅ 步骤 1:定义带参数的 route
// 使用 {id} 占位符composable("user/{userId}"){backStackEntry->// 从 backStackEntry 获取参数valuserId=backStackEntry.arguments?.getString("userId")?:"unknown"UserDetailScreen(userId=userId)}
✅ 步骤 2:跳转时传值
// 在 HomeScreen 中Button(onClick={navController.navigate("user/123")})

✅ 进阶:类型安全传参(推荐!)

使用 Navigation Safe Args(Compose 版) 或 自定义解析。

方法 A:手动解析(简单场景)
composable("user/{userId}"){entry->valuserId=entry.pathSegments[1]// ["user", "123"]UserDetailScreen(userId)}
方法 B:使用 navArgs + Parcelable(更安全)
// 定义数据类@ParcelizedataclassUserArgs(valid:String,valname:String):Parcelable// 跳转valargs=UserArgs("123","Alice")navController.navigate("user?args=${Uri.encode(args.toString())}")// 不推荐,复杂// 更推荐:直接拼接基础类型navController.navigate("user/${userId}")

📌 官方建议:

对于简单参数(String/Int),直接用 {param};

复杂对象优先通过 ViewModel 共享,而非导航传参。

🔙 五、返回并传递结果(类似 startActivityForResult)

Compose Navigation 原生不支持返回结果,但我们可以用 ViewModel + Shared State 实现。
✅ 推荐方案:共享 ViewModel

// 共享 ViewModel@HiltViewModelclassSharedViewModel@Injectconstructor():ViewModel(){privateval_selectedItem=MutableStateFlow<String?>("")valselectedItem=_selectedItem.asStateFlow()funselectItem(item:String){_selectedItem.value=item}}// 主页@ComposablefunSelectHomeScreen(viewModel:SharedViewModel,onNavigateToSelectItem:()->Unit){valselectedItembyviewModel.selectedItem.collectAsState()Column{Text("选中数据:${selectedItem}")Button(onClick=onNavigateToSelectItem){Text("选项选择")}}}// 选择页@ComposablefunPickerScreen(viewModel:SharedViewModel,onNavigateBackHome:()->Unit){Column{Button(onClick={viewModel.selectItem("选项A")onNavigateBackHome()}){Text("选项A")}}}

✅ 优点:解耦、可测试、支持跨多层返回

💡 注:HiltViewModel 如果没有这个注解,需要引入依赖:

implementation("androidx.hilt:hilt-lifecycle-viewmodel:1.3.0")

🌐 六、深度链接(Deep Link)

让外部链接(如网页、通知)直接打开 App 内页面。

步骤 1:在 composable 中注册 deep link

composable("profile",deepLinks=listOf(navDeepLink{uriPattern="myapp://profile"})){ProfileScreen()}

步骤 2:在 AndroidManifest.xml 中声明

<activityandroid:name=".MainActivity"><intent-filter><actionandroid:name="android.intent.action.VIEW"/><categoryandroid:name="android.intent.category.DEFAULT"/><categoryandroid:name="android.intent.category.BROWSABLE"/><dataandroid:scheme="myapp"android:host="profile"/></intent-filter></activity>

效果:点击 myapp://profile → 直接打开个人页!

🧪 七、测试导航

使用 createAndroidComposeRule + navigate() 模拟跳转。

@TestfuntestNavigateToProfile(){composeTestRule.setContent{MyApp()}// 点击按钮composeTestRule.onNodeWithText("去个人页").performClick()// 验证是否显示个人页内容composeTestRule.onNodeWithText("个人中心").assertExists()}

⚙️ 八、高级技巧

1. 嵌套路由(Nested Graph)

//TODO main是外层的路由路径,home是嵌套内开始展示UI的路由路径navigation(startDestination="home",route="main"){composable("home"){HomeScreen()}composable("settings"){SettingsScreen()}}composable("login"){LoginScreen()}

2. 自定义过渡动画

composable("profile",enterTransition={slideInHorizontally(initialOffsetX={it})},exitTransition={slideOutHorizontally(targetOffsetX={-it})}){...}
3. 拦截返回键
BackHandler(enabled=canExit){navController.popBackStack()}

✅ 十、最佳实践总结

  • 导航图集中管理:所有 composable 定义在一个地方(如 NavGraph.kt)
  • 参数尽量简单:用 ID 代替完整对象
  • 返回结果用共享状态:避免 hack 式回调
  • 深度链接提前规划:方便运营和分享
  • 动画适度使用:提升体验但别过度

🎯 结语

Jetpack Compose Navigation 不只是“页面跳转”,而是一套完整的页面生命周期管理方案。

它帮你处理了:

  • 返回栈
  • 状态保存(配合 rememberSaveable)
  • 深度链接
  • 动画过渡
  • 测试支持

只要掌握NavController+NavHost+composable三件套,你就能构建任意复杂的 App 导航结构!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/22 15:44:32

MiGPT终极教程:如何让小爱音箱变身智能AI语音助手

MiGPT终极教程&#xff1a;如何让小爱音箱变身智能AI语音助手 【免费下载链接】mi-gpt &#x1f3e0; 将小爱音箱接入 ChatGPT 和豆包&#xff0c;改造成你的专属语音助手。 项目地址: https://gitcode.com/GitHub_Trending/mi/mi-gpt 还在为小爱音箱的机械回答感到失望…

作者头像 李华
网站建设 2026/1/10 13:46:23

拼多多API助力,实现商品批量管理,提高运营效率!

在电商运营日益精细化的今天&#xff0c;高效管理海量商品信息已成为提升竞争力的关键。对于拼多多平台的商家而言&#xff0c;手动逐条操作商品不仅耗时耗力&#xff0c;更容易出错。而拼多多开放平台提供的API接口&#xff0c;则为商家们打开了一扇通往自动化、智能化运营的大…

作者头像 李华
网站建设 2026/1/9 14:45:55

终极指南:如何快速部署SynthPose-VitPose实现高精度人体姿态估计

SynthPose-VitPose模型是当前最先进的人体姿态估计解决方案&#xff0c;通过创新的合成数据训练方法实现了对52个关键点的精准检测。本文将带您从零开始&#xff0c;快速掌握这个强大模型的部署方法和使用技巧。 【免费下载链接】synthpose-vitpose-huge-hf 项目地址: https…

作者头像 李华
网站建设 2025/12/23 2:29:51

显卡驱动彻底清理大师:DDU完整操作指南与深度解析

显卡驱动彻底清理大师&#xff1a;DDU完整操作指南与深度解析 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-uninstaller …

作者头像 李华