When I'm hooking up the `up` button, I know that b...
# compose
c
When I'm hooking up the
up
button, I know that both
Copy code
navController.navigateUp()
and
navController.popBackStack()
do the same thing, but which one should be used for the up action specifically.
navigateUp
right?
👌 3
a
Here's an article that describes the difference: https://medium.com/@ianhlake/up-vs-back-5fae17a84a5f It talks about activities but also applies to composables.
o
Up always stays in your app, popBackStack() can get out of your app
s
The article indicates that it’s not as simple as just what you said here Orhan.
f
Looking at the source code, both
popBackStack()
and
navigateUp()
never leave the app.
o
Do you have a link to that part of the code?
Internally,
navigateUp()
uses
popBackStack()
, unless the app's back stack is empty.
Which is a little bit confusing after reading Ian's article 😄
o
Yeah, looking at the code, now Im confused
i
Both are correct: if you're following the Principles of Navigation and always exiting your task through the start destination of your app, then the only time you'd trigger navigateUp is when you've deep linked into your app from another app. That's exactly the case where navigateUp keeps you in your app (moving users to your own task)
c
So... Having my up button in my top app bar should always call popBackStack which will call navigate up if I've been deep linked? Or should I be writing that if statement myself?
f
I would say that neither is really applicable. See this graph as an example: https://material.io/design/navigation/understanding-navigation.html#types-of-navigation. When the user goes from search to a song, pressing the up button should navigate to the album. Still, both
popBackStack
and
navigateUp
would navigate to search. Or am I wrong?
i
Mostly just out of date, our most recent UX study results are codified in the Principles of Navigation, specifically: https://developer.android.com/guide/navigation/navigation-principles#up_and_back_are_identical_within_your_apps_task
You should always call navigateUp from a top app bar. It'll do the right thing
c
Perfect. That's all I really care about in the end. 😁 I'm going to fix the two screens that are using the pop method on their top app bar up button. Thanks for clarifying @Ian Lake I'm going to try to write a lint check to prevent a teammate from accidentally calling the wrong method!
f
@Ian Lake Thanks for the clarification!
i
I will mention that the idea of a "hierarchical parent" still exists - that idea is how the synthetic back stack is built when you deep link into your app from a notification, widget, etc. or when navigateUp actually takes you to your own task - that hierarchy is built from the start destinations of your navigation graph structure (so if you have nested navigation graphs, you'll get multiple entries on that synthetic back stack with the hierarchical parent at each level). That's all done for you, as per https://developer.android.com/guide/navigation/navigation-deep-link
f
When using nested `NavHost`s (which are, afaik, somtimes required for proper animations), deep linking probably has to be implemented manually, right?
i
If you add the same deep link to both graphs, it should work automatically. There's a lot of other reasons why nested NavHosts are a bad idea though, so I'd encourage you to file issues against Accompanist Navigation Animation for what animation support you want
f
My main problem would be solved if I could lay out children of
Scaffold
over the bottom bar, but I don't know if that can be easily implemented.
s
You mean so that the bottom bar is hidden? Could reducing the height of the bottom bar to 0 work in those cases? If I understood your use case correctly
a
@Felix Schütz I think you can easily achieve that by setting
Modifier.zIndex(1f)
on the composable you want it to be at top.
f
@Stylianos Gakis Yes, exactly. Reducing the height does not really work, because I want a clean transition when navigating, where the incoming composable is scaled and faded in over the bottom bar, while the outgoing composable is not animated. I could slide the bottom bar down, but that does not look as good in my opinion.
@Albert Chang When I last tried it, it did not work, since my architecture is
Scaffold > NavHost > Screen
. I need to change the
zIndex
of a specific screen, but this does not affect the drawing order in
Scaffold
.
a
I don't think it's possible if you keep this hierarchy. A composable can never control its indirect children.
f
So is there any alternative? Or do I need to keep using nested
NavHosts
?
s
If this isn’t possible I would say it’s quite important to be looked into. This sounds like a very normal use case and as multiple nav hosts are really discouraged this feels like a dead end of some sorts
f
I agree, but I don't know how I would want to have the possibility implemented, so I don't know how to file a bug 😄 Maybe some additional
NavGraphBuilder
function to insert common composables for certain destinations? I'm really unsure.
I opened an issue in Accompanist (https://github.com/google/accompanist/issues/729). I don't think this issue is really in scope of Accompanist, but maybe the issue receives some valuable feedback there.
j
We’re facing this issue as well. We have a concept of modal route destinations which we dynamically hide the bottom bar for, but as mentioned the animations are clunky. We also use bottom sheets within destinations, which should display above all the content (including the bottom bar). This feels like a simple requirement thats too hard to achieve, zIndex also didnt work for me
i
Bottom sheet destinations (via Accompanist Navigation Material) already allow you to have modal sheets that extend above a bottom bar simply by putting the
ModalBottomSheetLayout
above your global
Scaffold
And I'm not sure if you saw the update, but there is already an API for coordinating exactly when you want to start your own animation relative to Navigation's animation completing: https://github.com/google/accompanist/issues/633#issuecomment-942988181
j
As far as I was aware, accompanist navigation bottom sheets are for bottom sheet destinations. What if the bottom sheet is simply a menu for the current destination? I.e. a set of filters:
Having a separate destination for the bottom sheet makes no sense here because we’d be adding all the extra ceremony of sharing the data between the destinations
I hadnt seen that update, I’ll take a look. Does this allow us to trigger an animation which syncs perfectly with the transition animation of the screen? If the screen if crossfading out, I would expect the bottom bar to also crossfade exactly at the same time
i
Re: bottom sheets, yep only for separate destinations. The core issue that the
ModalBottomSheetLayout
must be as high up the Composable hierarchy as it needs to be to overlap everything inside it is just how that API works; nothing Accompanist provides will ever be able to change that - that whole core API would need to change
You can certainly time your crossfade to the same duration, etc. given that you are specifically the one controlling both animations, but you'd need to do that yourself - AnimatedContent only handles just its own transitions
o
@Jason Ankers Did you manage to solve your use case with "local" bottom sheet for the filter composable?
j
Not yet
👌 1