I'm using BottomNavigation in Jetpack Compose with navigation-compose:2.5.0-alpha04 and I want to encapsulate each tab's flow with nested navigation. To achieve this I created a single NavHost with different graphs inside:
NavHost(
navController = navController,
startDestination = defaultTab.route
) {
eventsGraph()
employeesGraph()
devicesGraph()
feedbackGraph()
}
Each graph contains its own composables inside a navigation extension function.
As docs suggest, when BottomNavigationItem is clicked, I'm configuring my NavOptions the following way:
onClick = {
navController.navigate(tab.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
// We want to reset the graph if it is clicked while already selected
restoreState = tab != currentTab
}
currentTab = tab
}
I'm expecting this code to ignore clicks on an already selected item and always having any selected tab as nav graph's root, i.e. quitting the app on back press if user is at the root destination of any given tab.
Instead, every click on a default tab at its start destination puts another instance of the same destination in the stack, and back press at a non-default tab puts me back to the defaultTab's destination.
I tried popping destinations inclusive, but NavController unsurprisingly just can't find saved Destination's ID to restore state for. I tried to saveState by the same tab != currentTab condition by which I restore it, but it appears to have no effect.
Is it possible to achieve desired behavior by the means of Navigation APIs or do I need to handle this by myself?
Update
I eventually came up with the following solution for resetting the current tab's graph. Basically, instead of navigating with popUpTo option we're just popping the stack to the start destination.
onClick = {
if (tab == currentTab) {
navController.popBackStack(
route = tab.startDestination,
inclusive = false
)
return@BottomNavigationItem
}
/* ... */
}
There is still an issue with defaultTab's graph being the root, which means pressing the back button on any non-defalut tab's start does not exit the app.
if (tab != currentTab) { navController.navigate(...) }?tab == currentTab, you want to pop everything up to the root of that stack?