google / accompanist

A collection of extension libraries for Jetpack Compose
https://google.github.io/accompanist
Apache License 2.0
7.45k stars 599 forks source link

[Navigation Animation] Provide backstack id when animating with multiple backstack #1293

Closed fabriciovergara closed 2 years ago

fabriciovergara commented 2 years ago

Description

In order to perform correct animation when navigating between parallel backstack, we need to have a backstack id provided in the enterTransition/exitTransition/popEnterTransition/popExitTransition

Steps to reproduce

Please consider using animated navigation with bottom navigation and implementing follow the official documentation

Tab-1 has destination A and B
Tab-2 has destination D and E

When Navigating between Tab-1 and Tab-2 we want to perform FadeOut-FadeIn transition When Navigating from A to B or D to E we want to perform a slide-bottom transition

Consider that you are now in this state:

You move Tab-1  BackStack to destination B
You move Tab-2 BackStack to destination E

if you try to navigate from Tab-1 to Tab-2, there is no way to know that it's a navigation between backstacks from the NavBackStackEntry provided in the enterTransition/exitTransition/popEnterTransition/popExitTransition callbacks. Then in this case, when navigating from Tab-1 to Tab-2, we are only able to know that it' a navigation from B to E, performing a slide-animation by default

The official documentation states that [NavDestination.hierarchy](https://developer.android.com/reference/androidx/navigation/NavDestination.Companion#(androidx.navigation.NavDestination).hierarchy()) would provide the all the destination until origin, but in this case it's always 2 destinations: current on top of the stack + root which is the same for all tabs.

Expected behavior

Access to BackStack Id from NavBackStackEntry

Additional context

With fragments it was possible to workaround it by using defining desired animation in the NavigationOption.

ianhanniballake commented 2 years ago

The official documentation assumes you are using a nested graph to encapsulate all of the destinations within a particular tab, hence why hierarchy tells you exactly what the selected tab is: there's a 1:1 mapping between your graphs and tabs.

You'll want to do the same here, similarly to what we do in the Animations in Navigation Compose blog post, which actually handles a similar case as its example.

Chozzle commented 10 months ago

@ianhanniballake I'm running into an issue where all 3 of my tabs can navigate to a single graph. For example the first tab lists "What's new" and can navigate to the same content contained in the other tabs. I cannot manage to set up the graph in a way that gives me enough information in initialState and targetState to decide if it needs a top level transition. When I click on a button, for example, Colors, under What's New, the targetState shows the hierarchy has replaced the whatsNewGraph with tokensGraph (from the second tab). whatsNewGraph contains the Colors destination too, but Navigation seems to randomly choose to use tokensGraph. Therefore it shows a top level transition when it shouldn't. Do you have any tips, or should I post a sample in the issueTracker?

Chozzle commented 10 months ago

This Stack Overflow issue also describes the issue. Using a nested graph doesn't solve the issue, since routes navigate via deep link logic: https://stackoverflow.com/questions/77307862/jetpack-compose-how-to-navigate-from-many-bottom-tabs-to-one-screen