news 2026/6/16 1:34:25

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进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 13:38:52

Obsidian日历插件实战指南:构建可视化笔记时间轴

Obsidian日历插件实战指南&#xff1a;构建可视化笔记时间轴 【免费下载链接】obsidian-calendar-plugin Simple calendar widget for Obsidian. 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-calendar-plugin 想要将零散的笔记转化为有序的知识体系吗&#x…

作者头像 李华
网站建设 2026/6/16 9:06:28

2025大模型部署革命:Gemma 3 12B如何让企业AI落地成本骤降80%

2025大模型部署革命&#xff1a;Gemma 3 12B如何让企业AI落地成本骤降80% 【免费下载链接】gemma-3-12b-it-GGUF 项目地址: https://ai.gitcode.com/hf_mirrors/unsloth/gemma-3-12b-it-GGUF 导语 谷歌Gemma 3 12B模型通过Unsloth优化技术实现性能跃升&#xff0c;配合…

作者头像 李华
网站建设 2026/6/14 17:52:24

如何快速开启GPU硬件加速?Hap视频编解码器完整配置指南

如何快速开启GPU硬件加速&#xff1f;Hap视频编解码器完整配置指南 【免费下载链接】hap-qt-codec A QuickTime codec for Hap video 项目地址: https://gitcode.com/gh_mirrors/ha/hap-qt-codec 在视频播放性能优化领域&#xff0c;GPU硬件加速技术正成为提升播放体验的…

作者头像 李华
网站建设 2026/6/14 6:06:10

ConvNeXt模型实战指南:5步教你快速上手深度学习新宠

ConvNeXt模型实战指南&#xff1a;5步教你快速上手深度学习新宠 【免费下载链接】ConvNeXt Code release for ConvNeXt model 项目地址: https://gitcode.com/gh_mirrors/co/ConvNeXt ConvNeXt深度学习模型作为2020年代的卷积网络新星&#xff0c;以其简洁高效的架构设计…

作者头像 李华
网站建设 2026/6/15 11:14:30

6、Linux游戏光盘的使用与游戏体验

Linux游戏光盘的使用与游戏体验 在Linux系统中,使用游戏光盘来体验各类游戏是一种有趣的方式。下面就来详细介绍相关的内容。 1. Knoppix用户权限使用 为了让Knoppix用户在必要时能够使用root权限,可以使用 sudo 命令。 /etc/sudoers 文件已配置为允许Knoppix用户像ro…

作者头像 李华