Compose中实现底部导航显隐及解决跳转后导航重置问题
解决Compose类型安全导航中底部导航选中状态异常重置问题
问题根源
你的代码仅在导航到Home页面时将selectedItemIndex设为0,但其他底部导航页面(如Profile、Settings等)的路由变化时,未同步更新选中索引。这导致切换到其他底部页面时,选中状态仍停留在首页;当从这类页面进入Details再返回时,视觉上就会出现导航被重置到首页的现象。
解决方案
修改OnDestinationChangedListener的逻辑,遍历所有底部导航项,匹配当前路由并更新对应的选中索引,确保所有底部页面的选中状态都能正确同步。
修改后的完整代码
@Composable fun HomeNav() { val navController = rememberNavController() var shouldShowBottomBar by rememberSaveable { mutableStateOf(true) } var selectedItemIndex by rememberSaveable { mutableIntStateOf(0) } LaunchedEffect(key1 = navController) { navController.addOnDestinationChangedListener { _, destination, _ -> shouldShowBottomBar = !destination.hasRoute(Details::class) // 遍历底部导航项,匹配当前路由更新选中索引 bottomNavItems.forEachIndexed { index, item -> if (destination.hasRoute(item.destination::class)) { selectedItemIndex = index return@forEachIndexed // 找到匹配项后终止遍历 } } } } Scaffold( bottomBar = { AnimatedVisibility(visible = shouldShowBottomBar) { NavigationBar { bottomNavItems.forEachIndexed { index, item -> NavigationBarItem( selected = selectedItemIndex == index, onClick = { selectedItemIndex = index navController.navigate(item.destination) { popUpTo(Home) { saveState = true } launchSingleTop = true restoreState = true } }, // 补充示例属性,可根据实际需求调整 icon = { Icon(item.icon, contentDescription = item.label) }, label = { Text(item.label) } ) } } } } ) { innerPadding -> NavHost( modifier = Modifier.padding(innerPadding), navController = navController, startDestination = HomeGraph ) { homeNavGraph(navController) } } }
额外注意事项
- 确保
bottomNavItems中的每个item.destination都对应正确的路由类(如Home::class、Profile::class等),否则路由匹配会失败。 rememberSaveable已保证selectedItemIndex在页面重建(如横竖屏切换)时不会丢失状态,无需额外处理。
内容的提问来源于stack exchange,提问作者BorkoC
相关产品推荐
相关产品推荐

