Android Navigation library deep linking: How to synthesise backstack - android

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.

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...

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.

Back stack is not getting cleared when navigating between activities using Navigation Component

I've two navigation graphs, one for login/sign-up(login_nav_graph) screens and one for home(home_nav_graph) screens. Each navigation graph has one activity and couple of fragments.
First I'm launching home_nav_graph, and checking if the user logged in or not. If the user not logged-in, I'm navigating to the login_nav_graph using its activity as the destination. And once the user is logged in successfully, I'm navigating to the home_nav_graph using the activity inside this graph as the destination.
Problem: When I navigate between these two navigation graphs, the back stack is not getting cleared. When I press the back button in login_nav_graph it's taking back to the screens in home_nav_graph.
I've already used the action elements like popUpTo, popToInclusive when navigating to the other graph but still back stack is not getting cleared.
Navigation component version I'm using: 2.3.0-alpha06
Update:
This is the sample project I've created to reproduce the issue - test-navigation.
Also, created an issue tracker for this problem.

Back navigation after deep link by navigation architecture component

When I open the app from a deeplink (user clicks on URL) and press back button I expect user to navigate to a previous fragment in my navigation graph but it just exits the app.
The documentation says that back navigation should work the same way as if it the user got to that screen naturally.
Can I somehow specify the desired backstack in my navigation graph? Or can be backstack formed automatically after a deeplink? For older version of the library I found out that after back press it should navigate to the root of my navigation graph but that does not happen.
As mentioned in the documentation :
When a user opens your app via an explicit deep link, the task back stack is cleared and replaced with the deep link destination. When nesting graphs, the start destination from each level of nesting—that is, the start destination from each element in the hierarchy—is also added to the stack.
the start destination of the graph also added to the stack.
So when you click on the back button, the start destination on the graph coming to the top of the stack.

Categories

Resources