My bottom navigation can't navigate to the start d...
# compose
f
My bottom navigation can't navigate to the start destination after opening a deep link. Any idea why?
This bug is mentioned here but as opposed to the accepted answer, it doesn't work for me with `2.4.0-beta02`: https://stackoverflow.com/questions/68456471/jetpack-compose-bottom-bar-navigation-not-responding-after-deep-linking
Still present even in 2.4.0 rc01
f
Thank you, that explains things
i
The main issue I see with apps is that they aren't using a nested graph for each bottom nav item. As per that issue, that is a requirement to have each tab have its own back stack when deep linking into one of the other tabs
j
Hey Ian, I am actually using nested graphs on the bottom items. It works perfectly when the app is closed, however, if the app is in background and handling deeplink in
onNewIntent
then reselecting the last selected bottom item always navigates to the deep link destination. The above issue tracker link summerizes the issue I am also having perfectly. Note that I am handling the deeplink in
onNewIntent
with
navController.navigate with a deep link request param and nav options
instead of using
navController.handleDeeplink
because I don't want the synthetic back stack to replace my current back stack, I am trying to preserve the last back stack state before deep linking happens. But there is always some corner case that is not behaving correctly. I wonder how YouTube for example does that
d
So are the guidelines to have a Nested graph per bottom nav item? Is this mentioned anywhere in the docs?
i
Well yeah, if you call
navigate
, all that is going to do by default is add that on whatever back stack you are on. It just does exactly what you told it to do
d
For sure, but I've been following the guidelines for bottom nav in https://developer.android.com/jetpack/compose/navigation#bottom-nav and that one talks about Screens only, not graphs. Save & Restore state and singleTop seem to do the job without these being Nested Graphs.. So I'm just not sure what's right here - are we going to run into this behaviour mentioned in the issuetracker when we add deeplinks (in a full compose app if that matters) ?
i
If
handleDeepLink()
is working as expected (with the caveat of always putting the user in an understandable, consistent place rather than the merge kind of behavior you are trying for), then the problem is with your custom logic in
onNewIntent
d
I was probably not clear here - I've not hit any problems yet with my bottom nav setup (set up like the link in the docs, with screens not nested graphs), it was more of a worry/question whether I've just missed something and I was trying to get ahead of possible problems.
j
Yes, might be something with my implementation on
onNewIntent.
However, I'm struggling to find a proper solution. I'ma quickly highlight the issue maybe anyone is able to provide help. • The app has 3 bottom navigation tabs, each associated with a nav-graph, consider
GraphA, GraphB, GraphC.
• The user is on
GraphB
- the app is in the background. • The app receives a deep link to
C1
onNewIntent
calls
navController.navigate(deeplink)
• The app correctly navigates to
C1
Now the problem,
C1
is on top of
GraphB
and this is normal, because
I added no navOptions
to the navigate function, so when
NavItemB
clicked nothing happens since nav component just added the deeplink destination on top of it's stack. Adding
navOptions
popupTo
navController.graph.startDestinationId will make
C1
to be pushed on top of the right nav-graph
GraphC
BUT pressing back now goes back to
GraphA
, meaning it has not respected the previous destination before the deeplink happened. What
navOptions logic
can be added or any other logic so that pressing back goes back to
GraphB,
or in other terms to previous destination before the deeplink.
i
That's not how multiple back stack works by default - system back takes you to the start destination, then out of the app - users would need to reselect bottom nav B to get back to the back stack for B, which should be there with all of its state
You can certainly write your own logic for tracking which tab is selected and not popUpTo the start destination - there's always a way to get from every "before" back stack to any "after" back stack if you map it out
the whole reason you don't see this behavior by default is because forcing users to remember 'oh I went to tab B first, so that's on the back stack, and then I went to tab C, so if I am on the root screen of C and hit system back I'll actually go back to B' has time and time again failed the obviousness test for users. Part of the predictive back work is to ensure that given a screenshot of an app, a user would always know what happens when they hit system back - they don't have to keep your back stack stuff in their head
YouTube is a prime example of where our UX study participants failed multiple times 🙂
j
Yes pressing the item B restores back the state and works, I just need to check whether the back press can have the same behavior. In the app, a normal backpress from any tab goes back to the start destination then out of the app, assuming deep linking did not happen. Adding popup to start destination restores back the normal behavior
I understand, it seems pretty logical .. I think going back to the start destination is enough .. thanks for keeping an eye here mate ✌️
148 Views