Jetpack Compose带底部栏的嵌套导航登录流跳转问题
解决方案
核心问题分析
当前MainBody内部自行创建了独立的NavHostController,导致它与根导航图的navController完全隔离,无法跨导航图跳转到Auth流程。要实现跨图导航,必须让整个导航体系共享根导航的NavHostController。
步骤1:传递根导航控制器到MainBody
修改根导航图中MainBody的调用,传入根navController:
@Composable fun RootNavGraph(navController: NavHostController) { NavHost( navController = navController, startDestination = CommonRoute.Splash.route, route = GeneralGraph.ROOT ) { composable(CommonRoute.Splash.route) { SplashScreen(navController = navController) } authNavigation(navController) // 传入根navController到MainBody composable(CommonRoute.MainBody.route) { MainBody(navController = navController) } } }
步骤2:修改MainBody,移除内部导航控制器
让MainBody直接使用传入的根导航控制器,不再自行创建:
@Composable // 移除默认的rememberNavController,强制传入根控制器 fun MainBody(navController: NavHostController) { Scaffold( bottomBar = { CustomBottomBar(navController = navController) } ) { Surface( modifier = Modifier .padding(it) .fillMaxSize() ) { MainNavGraph(navController) } } }
步骤3:完善导航跳转逻辑
在HomeScreen的onUserNotRegistered和ProfileScreen的onSignOut中,使用根导航控制器跳转到Auth图,并清理回退栈,避免用户返回已过期的会话页面:
fun NavGraphBuilder.mainNavigation(navController: NavHostController) { navigation(route = MainGraph.MAIN, startDestination = MainRoute.Home.route) { composable(MainRoute.Home.route) { HomeScreen( navController = navController, onUserNotRegistered = { navController.navigate(GeneralGraph.AUTH) { // 弹出到根导航的起始目的地,清理所有之前的页面 popUpTo(GeneralGraph.ROOT) { inclusive = false } // 防止重复添加相同目的地到栈中 launchSingleTop = true } } ) } composable(MainRoute.Post.route) { PostScreen(navController = navController) } composable(MainRoute.Profile.route) { ProfileScreen(navController = navController, onSignOut = { navController.navigate(GeneralGraph.AUTH) { popUpTo(GeneralGraph.ROOT) { inclusive = false } launchSingleTop = true } }) } } }
额外说明
popUpTo(GeneralGraph.ROOT)确保回退栈清理到根导航图,用户无法通过返回键回到MainBody相关页面launchSingleTop = true避免重复创建Auth导航图实例- 确保
GeneralGraph.AUTH是根导航图中authNavigation注册的路由,与根导航的路由体系一致
内容的提问来源于stack exchange,提问作者Jairo Rios Reyes
相关产品推荐
相关产品推荐

