Material 3 NavigationBarItem如何设置选中/未选中状态的不同图标
Jetpack Compose Material3 底部导航栏切换选中/未选中图标实现
效果对比
- 当前运行效果:

- 预期实现效果:

完全支持按选中状态切换不同图标,仅需对现有代码做两处调整即可实现:
- 调整
BottomNavItem密封类结构,分别存储选中态、未选中态两套图标资源 - 渲染导航项图标时,根据当前项的选中状态动态加载对应图标
具体实现代码
1. 修改密封类定义
将原来单一的icon参数拆分为选中、未选中两个图标参数,搭配Material图标库使用时,通常选Filled填充风格图标作为选中态、Outlined描边风格图标作为未选中态:
sealed class BottomNavItem( var title: String, var selectedIcon: ImageVector, var unselectedIcon: ImageVector, var screen_route: String ){ object Users: BottomNavItem( title = "Users", selectedIcon = Icons.Filled.AccountBox, unselectedIcon = Icons.Outlined.AccountBox, screen_route = "users" ) object Notifications: BottomNavItem( title = "Notifications", selectedIcon = Icons.Filled.Notifications, unselectedIcon = Icons.Outlined.Notifications, screen_route = "notifications" ) }
2. 调整NavigationBarItem图标渲染逻辑
在遍历生成导航项时,先判断当前项的选中状态,根据状态选择对应图标传入即可:
items.forEach { item -> val isItemSelected = currentRoute == item.screen_route NavigationBarItem( icon = { Image( imageVector = if (isItemSelected) item.selectedIcon else item.unselectedIcon, contentDescription = item.title ) }, label = { Text(text = item.title) }, alwaysShowLabel = true, selected = isItemSelected, onClick = { navController.navigate(item.screen_route) { navController.graph.startDestinationRoute?.let { screen_route -> popUpTo(screen_route) {saveState = true} } launchSingleTop = true restoreState = true } } ) }
注意:
NavigationBarItem会自动根据选中状态给图标、文字应用M3主题规定的对应颜色,无需手动额外设置图标颜色,即可匹配官方设计规范。
内容的提问来源于stack exchange,提问作者wbk727
相关产品推荐
相关产品推荐

