Has anyone been able to address the bug in Navigat...
# compose-android
j
Has anyone been able to address the bug in Navigation2 (
NavHost
) where you’re unable to return to a given “top level destination” after navigating to another “top level destination” with route args? To exit this erroneous state, you must manually pop the top-most “top level destination” from the back stack then everything works as it should. I’m able to reproduce this bug in the Now In Android app so I know it’s not a bug unique to my app/implementation. If anyone has any insights on how to work around this bug it would be more than appreciated.
🤨 1
@Ian Lake I’ve seen you comment on a lot of Navigation2 messages. Do you have any idea of why this is happening?
i
You haven't shared any code so there's no way for anyone to understand what you are doing
if you navigate to a top level destination without the
saveState
+
restoreState
flags, you are indeed going to run into issues
j
When clicking a destination in the NavBar I use the following code:
Copy code
fun navigateToTopLevelDestination(topLevelDestination: TopLevelDestination) {
    val topLevelNavOptions = navOptions {
        popUpTo(route = navController.graph.findStartDestination().route!!) {
            saveState = true
        }
        launchSingleTop = true
        restoreState = true
    }

    when (topLevelDestination) {
        TopLevelDestination.Home -> navController.navigate(NavDestinations.Home, topLevelNavOptions)
        TopLevelDestination.Schedules -> navController.navigate(NavDestinations.Times(), topLevelNavOptions)
        TopLevelDestination.Settings -> navController.navigate(NavDestinations.Settings, topLevelNavOptions)
    }
}
Looks like I was calling to a different function that was properly setting
saveState
+
restoreState
flags.
That addresses the simple use case. I still have an unexpected case where I navigate to a non-destination screen and from there I navigate to a top-level destination. If I hit the “initial” top-level destination again I see the previous screen and must pop it off the stack.
Backstack: top-level#1 -> details screen -> top-level#2 When I attempt to navigate to top-level#1 via the bottom nav bar I see details screen.
Is it expected to see details screen again even though I used a
popUp<top-level#1>
?
i
If you are using
saveState
and
restoreState
, the entire tab, including screens you have navigated to while on that tab, are expected to be saved and restored, yes
j
If I set
saveState
and
restoreState
selecting the top-level#1 nav bar item does nothing. Why is this?
i
The important thing is that you should never be mixing and matching navigating to a particular top level screen without those flags and with those flags
Your back stack should never be top-level#1 -> details screen -> top-level#2 because that indicates you aren't always using those flags consistently
j
I guess I’m not sure the true state of the back stack but instead this more or less represents the navigations being performed. > top-level#1 -> details screen -> top-level#2 So the app loads to the first top-level screen. Then the details page is opened, next a button launches to a second top-level screen. I’ve updated my code to use the same navOptions for routing to the top-level screens. The problem is when trying to return to the first top-level screen by selecting the item in the nav bar it shows the destination screen first. My concern is this would confused users.
i
So the app loads to the first top-level screen. Then the details page is opened, next a bug launches to a second top-level screen.
And the selected item on the nav bar shows them transitioning to the second tab at this point, yes? That's the signal to users that they've done the exact same thing as if they clicked on the second tab themselves
j
I had typo above, I meant “next a button launches to a second top-level screen”… As a user I would expect selecting an option in the nav bar would take me to corresponding destination and not the details screen.
i
Multiple tabs with history for each tab has been the standard for 4+ years on Android and has always been the case for iOS. I think you might be in the minority here