深入解析以太网DMA描述符:从原理到实战的高效网络数据传输
2026/7/22 17:24:38
在 Compose 中,你不再用Activity 跳转,而是用“声明式导航”:
Composable 函数改变当前“目的地”(Destination)从导航栈弹出Jetpack Compose Navigation 提供了一套统一、安全、带生命周期管理的导航方案。
implementation"androidx.navigation:navigation-compose:2.8.0"@ComposablefunHomeScreen(onNavigateToProfile:()->Unit){Column{Text("首页")Button(onClick=onNavigateToProfile){Text("去个人页")}}}@ComposablefunProfileScreen(){Text("个人中心")}@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 块对应一个页面
userId// 使用 {id} 占位符composable("user/{userId}"){backStackEntry->// 从 backStackEntry 获取参数valuserId=backStackEntry.arguments?.getString("userId")?:"unknown"UserDetailScreen(userId=userId)}// 在 HomeScreen 中Button(onClick={navController.navigate("user/123")})使用 Navigation Safe Args(Compose 版) 或 自定义解析。
composable("user/{userId}"){entry->valuserId=entry.pathSegments[1]// ["user", "123"]UserDetailScreen(userId)}// 定义数据类@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 共享,而非导航传参。
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")让外部链接(如网页、通知)直接打开 App 内页面。
composable("profile",deepLinks=listOf(navDeepLink{uriPattern="myapp://profile"})){ProfileScreen()}<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()}//TODO main是外层的路由路径,home是嵌套内开始展示UI的路由路径navigation(startDestination="home",route="main"){composable("home"){HomeScreen()}composable("settings"){SettingsScreen()}}composable("login"){LoginScreen()}composable("profile",enterTransition={slideInHorizontally(initialOffsetX={it})},exitTransition={slideOutHorizontally(targetOffsetX={-it})}){...}BackHandler(enabled=canExit){navController.popBackStack()}Jetpack Compose Navigation 不只是“页面跳转”,而是一套完整的页面生命周期管理方案。
它帮你处理了:
只要掌握NavController+NavHost+composable三件套,你就能构建任意复杂的 App 导航结构!