I'm using NavigationBar in Jetpack Compose and defining icons for each item, where the selected item should display a filled icon, and the unselected ones should show the default icon. However, the selected icon is always applied, even when an item is unselected.
Here’s my implementation:
@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(
selected = index == selectedItemIndex,
onClick = {
selectedItemIndex = index
},
icon = {
Icon(
imageVector = if (index == selectedItemIndex) item.selectedIcon else item.unselectedIcon,
contentDescription = "",
)
},
alwaysShowLabel = true,
)
}
}
}
The BottomNavigationItem data class is defined as:
data class BottomNavigationItem(
val selectedIcon: ImageVector,
val unselectedIcon: ImageVector,
)
Whenever I select a new item, selectedItemIndex updates correctly, but the index variable always seems to end up as 2. As a result, the selected icon is applied to all items instead of just the selected one.
Logs:
//here, i selected friends (index 0 on the list)
I index: 0 , selectedItemIndex: 0
I index: 1 , selectedItemIndex: 0
I index: 2 , selectedItemIndex: 0
//changed to profile (index 1 on the list)
I index: 0 , selectedItemIndex: 1
I index: 1 , selectedItemIndex: 1
I index: 2 , selectedItemIndex: 1
even though selectedItemIndex is correct, index always seems to end up as 2, affecting all items and their respective icons, and I don't have any clue about why this is happening. any help here is appreciated. thanks!
Edit: This NavigationBar is used alongside a Pager, allowing users to navigate either by tapping the bottom navigation items or by swiping left and right. However, since the issue seems to be related to how items are indexed, and it occurs regardless of whether I select an item via the NavigationBar or swipe in the Pager, I didn't initially include the Pager in the code snippet. As the forum guidelines suggest providing a minimal reproducible example, I focused only on the navigation bar, since it alone is apparently enough to reproduce the issue.
I'm using NavigationBar in Jetpack Compose and defining icons for each item, where the selected item should display a filled icon, and the unselected ones should show the default icon. However, the selected icon is always applied, even when an item is unselected.
Here’s my implementation:
@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(
selected = index == selectedItemIndex,
onClick = {
selectedItemIndex = index
},
icon = {
Icon(
imageVector = if (index == selectedItemIndex) item.selectedIcon else item.unselectedIcon,
contentDescription = "",
)
},
alwaysShowLabel = true,
)
}
}
}
The BottomNavigationItem data class is defined as:
data class BottomNavigationItem(
val selectedIcon: ImageVector,
val unselectedIcon: ImageVector,
)
Whenever I select a new item, selectedItemIndex updates correctly, but the index variable always seems to end up as 2. As a result, the selected icon is applied to all items instead of just the selected one.
Logs:
//here, i selected friends (index 0 on the list)
I index: 0 , selectedItemIndex: 0
I index: 1 , selectedItemIndex: 0
I index: 2 , selectedItemIndex: 0
//changed to profile (index 1 on the list)
I index: 0 , selectedItemIndex: 1
I index: 1 , selectedItemIndex: 1
I index: 2 , selectedItemIndex: 1
even though selectedItemIndex is correct, index always seems to end up as 2, affecting all items and their respective icons, and I don't have any clue about why this is happening. any help here is appreciated. thanks!
Edit: This NavigationBar is used alongside a Pager, allowing users to navigate either by tapping the bottom navigation items or by swiping left and right. However, since the issue seems to be related to how items are indexed, and it occurs regardless of whether I select an item via the NavigationBar or swipe in the Pager, I didn't initially include the Pager in the code snippet. As the forum guidelines suggest providing a minimal reproducible example, I focused only on the navigation bar, since it alone is apparently enough to reproduce the issue.
Share Improve this question edited Feb 10 at 18:41 tyg 16.1k4 gold badges36 silver badges48 bronze badges asked Feb 10 at 18:17 MuriloMurilo 371 silver badge4 bronze badges1 Answer
Reset to default 2Although I don't know what you mean by "the index variable always seems to end up as 2" (as the logs clearly indicate that that's not the case), the reason why you see the same icons regardless of the selection state is because you actually use the same icons.
For example, the icons
BottomNavigationItem(
selectedIcon = Icons.Filled.Group,
unselectedIcon = Icons.Default.Group,
)
are the same because Icons.Default
is internally defined as:
val Default = Filled
So in both cases the same icon Icons.Filled.Group
will be taken.
Make sure you actually use different icons, like - for example - the Outlined variants:
BottomNavigationItem(
selectedIcon = Icons.Filled.Group,
unselectedIcon = Icons.Outlined.Group,
)