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 👌