Jetpack Compose AnimatedNavHost替代NavHost后嵌套导航返回异常
问题根因
该问题由AnimatedNavHost与普通NavHost的返回事件分发、返回栈处理逻辑差异触发:
- 跳转路由"2"时执行
popUpTo("1") { inclusive = true }后,根AnimatedNavHost返回栈仅剩余路由"2"单条目,而嵌套在路由"2"内的Feature1NavHost持有独立返回栈,默认不会向根导航控制器上报自身栈状态 - AnimatedNavHost的返回拦截优先级高于普通NavHost,点击返回键会优先触发嵌套NavHost的返回逻辑,等嵌套NavHost返回栈完全清空后才会触发根AnimatedNavHost的返回逻辑,动画执行过程中返回事件拦截冲突就会导致屏幕闪烁,同时需要先清空嵌套栈才能触发根导航的退出逻辑,因此需要多次点击返回键
修复步骤
- 统一导航组件类型:所有嵌套NavHost全部替换为同版本的AnimatedNavHost,禁止混合使用普通NavHost和AnimatedNavHost,避免动画与返回栈逻辑兼容问题
- 手动接管嵌套导航返回事件:给嵌套的AnimatedNavHost关闭默认返回拦截,监听嵌套返回栈状态,栈内仅剩首屏时直接触发父导航控制器的返回逻辑
@Composable fun Feature1NavHost() { // 获取父级导航控制器 val parentNavController = findNavController() val nestedNavController = rememberAnimatedNavController() // 嵌套返回栈仅剩首屏时拦截返回事件 BackHandler(enabled = nestedNavController.backQueue.size == 1) { parentNavController.popBackStack() } AnimatedNavHost( navController = nestedNavController, startDestination = "feature1_home", // 关闭AnimatedNavHost默认返回拦截 enableOnBackPressed = false ) { composable("feature1_home") { Feature1HomeScreen() } // 其余内部路由配置 } } - 调整跳转逻辑避免状态残留:Screen1跳转到路由"2"的代码补充
saveState = false配置navController.navigate("2") { popUpTo("1") { inclusive = true saveState = false } } - 可选优化:如果不需要Feature1模块的独立导航能力,直接将Feature1内部路由合并到根AnimatedNavHost中,彻底避免嵌套导航的返回事件冲突
内容的提问来源于stack exchange,提问作者MohanRaj S
相关产品推荐
相关产品推荐

