Thomas
02/08/2024, 9:44 AMThomas
02/08/2024, 9:44 AMroute parameter:
//snippet
navigate(
route = route, //route argument is "a" or "b" or "c"
navOptions {
popUpTo(graph.findStartDestination().id) {
saveState = true
}
restoreState = true
launchSingleTop = true
}
)
If we navigate to "a" through a deep link, the app behaves perfectly as expected.
The issue is, if we navigate to "b" or "c" (which are not the starting destinations) through deep link, then attempt to navigate to "a" through the "standard navigation function" above, we cannot navigate to "a" at all.
*
To debug this issue I tried changing the navOptions configuration I noticed that:
1. setting launchSingleTop to false does not fix the issue
2. setting restoreState to false fixes the issue, but that completely breaks the intended design.
3. setting saveState to false fixes the issue, but again that completely breaks the intended design.
4. setting both saveState and restoreState to false also fixes the issue, but again that completely breaks the intended design.
I have no clue what went conceptually wrong here, any clues would help. Thanks again for your time!Thomas
02/08/2024, 9:45 AMThomas
02/08/2024, 10:10 AMIan Lake
02/08/2024, 3:08 PMnavigation element, even if that nested graph only has a single destination in it - that's what tells the NavController to save a back stack for A before going to B, thus ensuring that you aren't just stacking everything on A's back stack (which is the behavior you're seeing now and why clicking on A isn't doing anything - you're already on the A back stack)Thomas
02/09/2024, 2:21 AMNavHost has a single NavController (regardless of whether or not the underlying NavGraph involve nested graphs), and a NavController holds a single backstack.
I don't understand what you mean by "tells the NavController to save a back stack for A before going to B".
I suppose my previous understanding is wrong and a NavController can hold on to multiple back stacks? like one extra back stack for every single nested graph?Ian Lake
02/09/2024, 2:26 AMsaveState and restoreState are exactly the APIs that are saving a back stack and then later restoring that back stack, yesThomas
02/09/2024, 2:27 AMNavController can hold on to multiple back stacks?Ian Lake
02/09/2024, 2:28 AMThomas
02/09/2024, 2:29 AMThomas
02/09/2024, 5:08 AM"which is the behavior you're seeing now and why clicking on A isn't doing anything - you're already on the A back stack"
I don't understand why this caused the issue, with the simple NavGraph structure I suppose there is just a single stack?
What has the deep link navigation changed?Ian Lake
02/09/2024, 5:22 AMThomas
02/15/2024, 2:50 AMThomas
02/15/2024, 3:11 AMNavHost(
modifier = Modifier.weight(1f),
navController = navController,
startDestination = "a",
) {
deepLinkTestingComposable("a")
deepLinkTestingComposable("b")
deepLinkTestingComposable("c")
}
As we deep link toward b, NavController navigates to a first as it is the starting destination, then navigates to b adding b to the current back stack.
The back stack at this point is b stacked on top of a, and a on top of null.
Next we call:
navigate(
route = a,
navOptions {
popUpTo(graph.findStartDestination().id) {
saveState = true
}
restoreState = true
launchSingleTop = true
}
)
I now understand that this actually don't make sense architecturally as you have explained in your reply,
yet I don't understand why we cannot navigate to a using this call, at all!
graph.findStartDestination().id should resolve to the ID of a, and with `popUpTo`'s inclusive being false by default, I thought b would be popped.
Yet b is not popped and the call does nothing as we remain on b... why is this the case?Ian Lake
02/15/2024, 4:11 AMThomas
02/15/2024, 4:24 AM/**
* Whether this navigation action should restore any state previously saved
* by [PopUpToBuilder.saveState] or the `popUpToSaveState` attribute. If no state was
* previously saved with the destination ID being navigated to, this has no effect.
*/
@get:Suppress("GetterOnBuilder", "GetterSetterNames")
@set:Suppress("SetterReturnsThis", "GetterSetterNames")
public var restoreState: Boolean = false
but I thought restoreState controls whether the state of the destinations should be restored if possible, and not the stack itself? 🤔Ian Lake
02/15/2024, 4:25 AMThomas
02/15/2024, 8:44 AMrestoreStateInternal and I think I understand now 👌