Reputation: 936
My BottomNavigationBar has 4 items, I want to navigate to the last item when the user clicks a button.
Here is my BottomNavigationBar:
@Composable
fun BottomNavigationBar(navController: NavController) {
val items = listOf(
BottomNavigationItem.Home,
BottomNavigationItem.Explore,
BottomNavigationItem.Favorites,
BottomNavigationItem.Profile
)
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
BottomNavigation(
backgroundColor = colorResource(id = R.color.purple_700),
contentColor = Color.White
) {
Row(horizontalArrangement = Arrangement.Center) {
items.forEachIndexed { i, item ->
if (i == items.count() / 2) {
Spacer(Modifier.weight(1f))
}
BottomNavigationItem(
icon = {
if (currentRoute == item.route) {
Icon(painterResource(id = item.iconPressed), contentDescription = item.title)
} else {
Icon(painterResource(id = item.iconNormal), contentDescription = item.title)
}
},
selectedContentColor = Color.White,
unselectedContentColor = Color.White,
alwaysShowLabel = false,
selected = currentRoute == item.route,
onClick = {
navController.navigate(item.route) {
navController.graph.startDestinationRoute?.let { route ->
popUpTo(route) {
saveState = true
}
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
}
}
and here is how I try to navigate to the "Profile" screen when the user clicks a button (in my MainActivity NavGraph):
composable(BottomNavigationItem.Favorites.route) {
FavoriteScreen(navigateToProfile = {
navController.navigate(BottomNavigationItem.Profile.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
})
}
Unfortunately this gives me a weird behaviour that my BottomNavigationBar is not working correctly, mostly the first screen is not opening anymore.
Something is getting mixed up and the "HomeScreen" bottomNavItem navigates to the "ProfileScreen" after the remote navigation.
What is the correct way to remotely navigate the bottomNavigationBar?
Upvotes: 3
Views: 1579
Reputation: 442
After several hours of struggling with a similar issue myself, I eventually created a bug report and a sample project demonstrating this issue. It was marked as a duplicate and not a bug.
If you want to emulate swapping to another tab, make sure to use the exact same flags as your BottomNav uses to actually swap from the back stack associated with one tab to the back stack associated with the other tab.
So, what I've decided to do since then is extend NavHostController
and just always call switchTabs
from both inside of my BottomNavigationItem.onClick
and from any buttons that I would like to result in the tab switching.
fun NavHostController.switchTabs(route: String) {
navigate(route) {
// Pop up to the start destination of the graph to
// avoid building up a large stack of destinations
// on the back stack as users select items
popUpTo(graph.findStartDestination().id) {
saveState = true
}
// Avoid multiple copies of the same destination when
// reselecting the same item
launchSingleTop = true
// Restore state when reselecting a previously selected item
restoreState = true
}
}
For me this has resulted in a much more sane navigation structure and has removed all of my issues where tapping on the bottom nav would appear unresponsive.
Upvotes: 1