Android navigate up the right graph when using NavController - android

I'm currently using Android Navigation Architecture in my project. It has a feature that can launch any fragment with a shortcut.
Suppose my navigation graph looks like this: A->B->C->D.
When I'm at fragment A , I directly navigate to fragment D with NavController.navigate(R.id.fragment_d). But when I'm press back button, it returns to fragment A. Is there any way to let the destination navigate back to its parent in navigation graph? (I mean, in this case, D back to C, B then back to A).
Thanks in advance.

Generally, you should always avoid creating a synthetic back stack when within your own app (and only do this when launching your app from a deep link outside your app, i.e., via an app shortcut).
However, you can approach this in one of two ways:
If you're okay with resetting the state on A, you can use NavDeepLinkBuilder to construct a set of Intents suitable for restarting your task on the chosen destination:
navController.createDeepLink()
.setDestination(R.id.destination_d)
.createTaskStackBuilder()
.startActivites()
Just call navigate() multiple times.
navController.navigate(R.id.destination_b)
navController.navigate(R.id.destination_c)
navController.navigate(R.id.destination_d)

I think you should be able to use navControler.navigateUp() on the destination if you have correctly introduced the parent fragment for your fragments. Also, consider the difference between the device back button and up back-arrow to go up to the parent

Related

Android Navigation Component popupTo self

I'm using Navigation Component to navigate in my app. I'm working with tree structure and I'm navigating users node by node -> Node == NodeFragment. But now I'm struggling with back navigation to particular node.
E.g.: Image navigation stack with look like this A -> B -> C -> D when user wants to navigate from node D directly to node B I want to popup fragment C, D and go directly to B?
E.g.: You can imagine something like navigating trough folder structure where you are navigation the same fragment again and again. And then you want to go back to particular folder which is not parent of the current one.
But I don't know ho to achieve it with Navigation Component. For navigation I'm using self action. Thanks in advance.
<fragment
android:id="#+id/nodeFragment"
android:name="com.example.NodeFragment">
<action
android:id="#+id/action_chatbotBuilderChildrenFragment_self2"
app:destination="#id/nodeFragment" />
</fragment>
So I found some kind of workaround solution which is pretty simple. It seems that calling NavController.navigateUp() multiple times in sort period of time works just fine. I'm not sure if this is the right solution but it solves my issues.
I was also supprise that even my fragment transition wasn't break after call NavController.navigateUp() multiple times.
Code example:
repeat(numberOfPopUps) {
findNavController().navigateUp()
}
Go into your navigation graph, click on the action (the arrow line) on C -> D, on the right panel (make sure in design mode instead of split or code mode) you will see pop up tp option, then choose Fragment B, that's it. So whenever you are in Fragment D and you click the Back key, the app will nagivate back to Fragment B.

MVVM Single Activity app return to a nested fragment with Navigation component after leaving app or launching intent

I am trying to return to a specific fragment after pressing the home button, sharing data with another app or switching activities.
Fragments in bottomNav:
A B C D
Fragments that are shared around the app and can be nested or navigated to from the bottomNav fragments:
E F G
Intended behaviour
User navigation stack:
A -> E
Presses home button and reopens app, stack remains the same.
A -> E
Actual Behaviour
User navigation stack:
A -> E
Presses home button and reopens app, brought back to first fragment
A
I tried to restore the navigation state by passing a bundle from navController.saveState() to a viewmodel during the Main Activity onPause method and restoring it with navController.restoreState() onResume to no avail. Is this not capable with the navigation component?
What you are looking for is called Multiple Backstack. Every Fragment in android maintains its own stack. So if you navigate to another Fragment in the ParentFragment, your ParentFragment will add the childFragment in its stack.
In your case, your ParentFragment is A and childFragment is E.
However, NavigationComponent has no vanilla support for Multiple Backstack. Ian Lake, the creator of NavigationComponent library is working on this issue since NavigationComponent was launched, and still haven't delivered on it. This doesn't mean he is not working on it, it simply means (as stated by Ian himself) that its harder to achieve because of Fragments API.
Coming back to your question, if you really want to implement MultipleBackstack then you can follow this project which pretty much anyone who wants MultipleBackstack with NavigationComponent first refers to. There is also a google sample that shows how to achieve this behavior.

android intent filter with single activity architecture

im currently working on an app, and i want to be able to share images to my app.
with multiple activities this doesn't seem to be a problem, since you define your activity as intent receiver.
however how would i do this, with the single activity architecture google is pushing with its navigation api ?
should the single main activity handle it or does it make sense to create a second activity in this scenario.
i couldn't really find anything on that topic in the android dev docs
Pass Uri to your navController instead of navigating manually by fragment id.
val deeplink = Uri.parse("android-app://androidx.navigation.app/yourFragmentId")
findNavController().navigate(deeplink)
Unlike navigation using action or destination IDs, you can navigate to any URI in your graph, regardless of whether the destination is visible. You can navigate to a destination on the current graph or a destination on a completely different graph.
When navigating using URI, the back stack is not reset. This is unlike other deep link navigation, where the back stack is replaced when navigating. popUpTo and popUpToInclusive, however, still remove destinations from the back stack just as though you had navigated using an ID.

Back navigation after deeplink 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.
I’m using the navigation library from Android architecture components (version 1.0.0-beta01).
I found out what's going on here, for explicit deep links its supposed to go to a new back stack which is what you app would have if a user had naturally navigated to the view not the existing back stack (existing stack is cleared.
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. This means that when a user presses the Back button from a deep link destination, they navigate back up the navigation stack just as though they entered your app from its entry point.
For implicit its a bit strange. You can make it do what explicit does but setting Intent.FLAG_ACTIVITY_NEW_TASK otherwise the back button and the navigation up button do two separate things:
The back button will do as you might expect, it will go back in your apps existing back stack and load that fragment.
The up button however will clear the a back stack and make a new one as if it was an explicit link.
If the flag is not set, you remain on the task stack of the previous app where the implicit deep link was triggered. In this case, the Back button takes you back to the previous app, while the Up button starts your app's task on the hierarchical parent destination within your navigation graph.kquote
Source: Android Documentation
As describe here back button should return to the previous fragment, you can set it manually in Java like this: button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.next_fragment, null));
In Kotlin like that: button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.next_fragment, null))
The Android system maintains a back stack containing the last visited destination. The first destination of your app is placed on the stack when the user opens the app. Each call to the navigate() method puts another destination on the top of the stack. Conversely, pressing the Up or Back button calls the NavController.navigateUp() and NavController.popBackStack() methods, respectively, to pop the top destination off of the stack.
Make sure that you are using NavHostFragment and not <fragment> in your hosting fragment activity.

Launching deep level activity

I have a main activity where user provides an input according to which i jump to a activity deep inside the heirarchy eg:
Let activities be B->C->D->E
On user input it will jump from A to E.What i want to do is i want to add B C D onto the backstack so that when user press back button it navigate according to the heirarchy. Also i want to remove A from the backstack so after B app should exit. I know there are many related questions but I am not able to make out how exactly to do this. I have been following the tutorial for providing proper back navigation on android official site:Create Back Stack. In this tutorial i did not understand how PendingIntent is used or what upIntent is.I am new to android development so any help will be appreciated.ThankYou
Sounds like you need to use fragments within 1 activities framelayout. You can use FragmentManager to manage the backstack
more info:
http://developer.android.com/reference/android/app/FragmentManager.html

Categories

Resources