Jetpack Compose底部导航栏实现受阻,需完成点击跳转逻辑
完成Jetpack Compose底部导航栏实现
直接替换你现有的BottomNavigationBar代码,以下是完整实现:
@Composable fun BottomNavigationBar(navController: NavHostController) { val navBackStackEntry by navController.currentBackStackEntryAsState() val currentRoute = navBackStackEntry?.destination?.route // 直接使用Navigation对象列表,方便获取每个项的label和icon val navigationItems = listOf( Navigation.Home, Navigation.Profile, Navigation.Search ) BottomNavigation( // 可根据主题自定义背景色 backgroundColor = MaterialTheme.colorScheme.surface ) { navigationItems.forEach { item -> BottomNavigationItem( icon = { Icon( painter = painterResource(id = item.icon), contentDescription = item.label ) }, label = { Text(text = item.label) }, // 判断当前导航项是否选中 selected = currentRoute == item.route, onClick = { // 避免重复点击同一导航项触发无效导航 if (currentRoute != item.route) { navController.navigate(item.route) { // 回到栈起始位置,避免页面重复入栈 popUpTo(navController.graph.startDestinationId) { saveState = true } // 恢复之前保存的页面状态(比如列表滚动位置) restoreState = true // 确保同一页面在栈中只存在一个实例 launchSingleTop = true } } }, // 自定义选中/未选中的颜色 selectedContentColor = MaterialTheme.colorScheme.primary, unselectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant ) } } }
关键修改说明
- 调整导航项数据源:把原来的路由字符串列表改成
Navigation对象列表,直接复用密封类里的label和icon,无需额外映射。 - 简化选中状态判断:通过当前路由和导航项路由直接对比,不需要额外维护
currentItem状态(如果不需要外部使用该状态,可直接移除原参数)。 - 优化导航逻辑:
- 加入路由判断,避免重复点击同一导航项时的无效操作。
- 用
popUpTo+saveState、restoreState实现页面状态的保存与恢复,提升切换体验。 launchSingleTop = true保证同一页面在栈中仅存一个实例,避免栈冗余。
组件使用示例
在包含NavHost的主布局中,通过Scaffold挂载底部导航栏:
@Composable fun MainScreen(navController: NavHostController) { Scaffold( bottomBar = { BottomNavigationBar(navController = navController) } ) { paddingValues -> NavHost( navController = navController, startDestination = Navigation.Home.route, modifier = Modifier.padding(paddingValues) ) { composable(Navigation.Home.route) { HomeScreen() } composable(Navigation.Profile.route) { ProfileScreen() } composable(Navigation.Search.route) { SearchScreen() } } } }
内容的提问来源于stack exchange,提问作者hefli ooki
相关产品推荐
相关产品推荐

