Jetpack Compose NavigationBarItem图标选中状态异常问题求助
问题分析与解决方案
你的代码逻辑本身是正确的,日志也显示index和selectedItemIndex的匹配没有问题,出现所有图标都显示选中状态的原因是Compose重组时的组件复用机制没有正确识别每个NavigationBarItem的唯一性。
在Compose中,当通过循环创建多个同类型组件时,必须为每个组件指定唯一的key参数,否则Compose会默认根据组件在布局中的位置来跟踪状态。当selectedItemIndex变化触发重组时,这种基于位置的跟踪可能导致组件状态错位,最终出现所有图标都显示为选中状态的异常。
修改后的代码
只需要在NavigationBarItem中添加key参数,使用循环的index作为唯一标识即可:
@Composable fun MyNavBar() { var selectedItemIndex by rememberSaveable { mutableIntStateOf(0) } val itemsBarList = listOf( BottomNavigationItem( selectedIcon = Icons.Filled.Group, unselectedIcon = Icons.Default.Group, ), BottomNavigationItem( selectedIcon = Icons.Filled.Person, unselectedIcon = Icons.Default.Person, ), BottomNavigationItem( selectedIcon = Icons.Filled.Settings, unselectedIcon = Icons.Default.Settings, ), ) NavigationBar { itemsBarList.forEachIndexed { index, item -> Log.i("HomePager", "index: $index , selectedItemIndex: $selectedItemIndex") NavigationBarItem( key = index, // 添加唯一key标识 selected = index == selectedItemIndex, onClick = { selectedItemIndex = index }, icon = { Icon( imageVector = if (index == selectedItemIndex) item.selectedIcon else item.unselectedIcon, contentDescription = "", ) }, alwaysShowLabel = true, ) } } }
补充优化建议
如果你的BottomNavigationItem有自身的唯一业务标识(比如路由路径、自定义ID等),用这些标识作为key会比index更可靠——尤其是当列表项可能发生增删、排序操作时,index会变化,容易导致组件状态丢失。示例如下:
// 给BottomNavigationItem添加唯一业务标识 data class BottomNavigationItem( val route: String, // 比如对应导航路由 val selectedIcon: ImageVector, val unselectedIcon: ImageVector, ) // 循环时用业务标识作为key NavigationBarItem( key = item.route, // ...其他参数保持不变 )
内容的提问来源于stack exchange,提问作者Murilo
相关产品推荐
相关产品推荐

