Android Navigation Components popupto logic with shared screens - android

So I have an interesting flow of screens in our app. Feature A and Feature B with a shared end flow at the end. I am not sure best practices for implementing the popupto in the navigation graph
So feature A's flow goes like this
Main - > Feature A Screen 1,Feature A Screen 2, Shared Flow Screen 1, Shared Flow Screen 2.
I want to popupto Feature A Screen 1 when launching Shared end flow Screen 2. Which is obvious when you are not doing a shared end flow. But lets say I had another flow like
Main - > Feature B Screen 1,Feature B Screen 2, Shared Flow Screen 1, Shared Flow Screen 2.
I am not able to set popupto to Feature B Screen 1 and Feature A Screen 1 in the nav graph.
I have thought of different solutions but are not sure on best practices
Put Feature A and B into a nested nav graph where popupto the whole nav graph not inclusive and deep link
Dynamically change the nested nav graph start destination to Feature A or B and popup to the nav graph.
Have 2 different nav graphs for the 2 flows and for the different nav graphs have different popuptos
Pass popupto param to the nav graph to say where to go back
Somehow inspect the nav graph to identify where they came from and popupto via code.
Any blog articles on this or what do you think you would do in this situation. I am not sure if all of these situations would work but I am exploring 3 but it will require duplication of nav graph code.

I also was unable to find an elegant solution to the problem, but I was able to get the desired result by adding a intermediate screen, which immediately forwards to the shared screen. I could then popUpTo that fragment, with popUpToInclusive set to true. I hope this might be helpful.

Related

How to exit feature's navigation graph?

I have a feature as a module which consist of 3 fragments.
After User navigates to the 3'd fragment, there is a computation, when computation succeeds -> User should be navigated to the Home screen which is in the parent nav graph.
I've tried a lot of approaches, but nothing seem to work correctly, is there a way to finish current navigation graph and return to the parent graph?
Things I've tried:
Navigation to the home with a help of deeplink. Not a bad option, but it messes with backStack, and it is not user friendly in case feature will be exposed to different clients.
Navigating to the start destination with cleaning of the backstack and after navigateUp. Better option than the first, but still...

Wrong animation when using popUpTo in Android

I'm doing a nav graph in an Android project where I have a number of fragments - let's just assume for now that I have 3 (fragment A, B and C).
I have navigation actions between the fragment like this: A -> B, B -> C, and finially a global action always just pointing to A (Since the app is way bigger than 3 fragments and fragment A is a start screen, so it makes sense to have a global action going back to the start screen).
From fragment C I can go back to A with the global action (which is also using popUpTo and Inclusive, to clear the backstack totally).
Now the issue - I'm using transition animations when transitioning between the fragments and they work - except for the global action where I'm using popUpTo. I wish to use a from_left and to_right animation as enter/exit, which works exactly as intended on other fragments, but for the global action the exit animation is wrong (looks kinda like the fragment is moving out to the left of the screen instead of out to the right).
The weird thing is: If I set the popUpTo behaviour to "none", it works perfectly fine, animation plays as intended.
So, is there something one should be aware of about transition animations when using popUpTo in the nav graph?

Android Navigation: removing an activity from the backStack

This question is related specifically to the androidx.navigation library.
I split up my primary graph into 2 graphs because I wanted to have one with a bottom nav with the fragments above it and one without. Instead of using <include... I added the activity to the first graph
<activity
android:id="#+id/Activity2"
android:name="com...Activity2"
android:label="Activity2" />
This all works nicely, but I also have a splash screen in the first graph that checks if the user is authenticated and navigates them directly into the second graph. With a fragment I can just use the standard popTo and popToInclusive to manage the fragment backstack but I have not been able to figure out how to do this with two activities so that when the second activity is launched the first is killed and removed from the backstack so the user cannot navigate backwards.
Currently I am just handling it in the fragment where the navigation occurs
navController
.navigate(R.id.action_someFragment_to_anotherFragment)
requireActivity().finish()
and this works but it leaves room for error and I'd like to deal with it with the navigation library if possible.
Each individual NavController is totally independent from one another. While an <activity> destination allows you to use navigate() to go to an entirely separate activity (which may or may not use Navigation itself), Navigation itself will never finish() an activity as part of a navigate() call so you'd need to do that yourself.
Using multiple activities with different navigation graphs is not the recommended way to handle authentication in Navigation as per the the Navigating Navigation talk and this approach fails in many ways (such as deep linking and invalidation after process death/recreation) that are correctly handled by the guide for handling login. When using one NavController and the ability to listen for navigation events, you do not run into these issues.

Android Navigate Component navigate to sub graph

I hava two Fragment(OverviewFragment、PersonalFragment), and one sub graph(contains two Fragment :BucketsFragment and ObjectsFragment, BucketsFragment is start destination). They are bind to one BottomNavigateView.
Now, After navigate to the sub graph start destination(BucketsFragment), and continue to navigate to ObjectsFragment. Then navigate to OverviewFragment and finally return to the sub graph.
Now, I came to start destination(BucketsFragment), but actually what I want is ObjectsFragment. what should I do?
The whole process is shown here
I want to navigate to the sub graph that retains the previous state, instead of a new sub graph.
As per the material design guidelines for bottom navigation:
On Android: the app navigates to a destination’s top-level screen. Any prior user interactions and temporary screen states are reset, such as scroll position, tab selection, and in-line search.
So technically, this behavior is expected.
When you're on the Resources tab and go to the ObjectsFragment, the back stack is
DashBoardFragment -> BucketsFragment -> ObjectsFragment
When you go back to the Overview tab, the back stack becomes
DashBoardFragment
And no state is saved for Fragments that aren't on the back stack. That's why when you reselect the Resources tab, it is recrated from scratch and you get back to
DashBoardFragment -> BucketsFragment
There's an existing issue for supporting multiple back stacks which aims to bring support for saving the state of each tab separately, allowing the behavior you wish. As per that issue, this requires significant changes to how Fragments work (since they are the one saving the state of Fragments) as well as integration into Navigation itself.
That issue points out a temporary workaround, demonstrated in the NavigationAdvancedSample where each tab uses its own separate navigation graph and separate NavHostFragment, thus allowing each one to keep its own state independently from one another. This requires a bit different of a setup in the MainActivity and the help of a set of NavigationExtensions to get that working.
It is expected that all of that functionality, once the multiple back stacks work is done, to be folded into the Navigation library itself.

Android Navigation library deep linking: How to synthesise backstack

Using Android Architecture's Navigation component, I have the following navigation graph
-> [Home] -> [Articles List] -> [Specific Article]
I also have a deeplink to [Specific Article]. When it is opened, navigating up currently goes to [Home].
I'd like to synthesise a backstack such that navigating up instead goes back to [Articles List] (and then on to [Home] if navigating again).
What is the Navigation way of doing this?
Per the NavDeepLinkBuilder documentation, Navigation uses the startDestination of the destination for the synthetic back stack. If you Group destinations into a nested navigation graph, both the startDestination of the nested graph and the startDestination of the root graph are added to the back stack. This gives you the ability to have [Articles List] as the startDestination of the nested graph to add it to your back stack.
However, it is strongly recommended to keep your synthetic back stack as small as possible - while a depth of 2 or 3 (as here) is fine, it is not recommended to go much beyond that level to avoid cases where users have to repeatedly tap and tap the back button to get back to the launcher.
The documentation implies that my original solution should work.
When a user uses the Back button from a deep link destination, they navigate back up the navigation stack just as though they entered your app from the app’s entry point.
In addition, ianhanniballake's answer doesn't produce expected results (the deeplinked fragment is not opened).
I have created an issue on google's tracker for both these problems: https://issuetracker.google.com/issues/79734195
I came across this thread while using navigation compose. The issue for me was that I called navController.popBackStack() instead of the correct navController.navigateUp(). After changing my calls to navigateUp(), everything works as expected. Maybe this helps someone with the same problem.

Categories

Resources