Android Navigation Component popupTo self - android

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.

Related

Android Navigation component deeplink backstack

I am doing navigation component codelab.
In 10 part we add deeplink widget.
I replace destination to R.id.flow_step_two_dest
val custAtgs = FlowStepFragmentArgs(2)
val pendingIntent = NavDeepLinkBuilder(context)
.setGraph(R.navigation.mobile_navigation)
.setDestination(R.id.flow_step_two_dest)
.setArguments(custAtgs.toBundle())
.createPendingIntent()
And have this graph
It works. After press back it is returned to home, but I expect that it will return to Step One.
Is it right behavior? Or am I doing something wrong?
It is the intended behavior.
This is from step 10 :
The backstack is generated using the destinations specified with
app:startDestination. In this app we only have one activity and one
level of navigation, so the backstack will take you to the home_dest
destination.
Pressing the back button should take you back to home_dest.
More complicated navigation can include nested navigation graphs. The
app:startDestination at each level of the nested graphs determines the
backstack.
Wrap flow_step_one_dest and flow_step_two_dest into a nested graph and set flow_step_one_dest as the start destination.
Pressing the back button should take you back to flow_step_one_dest then home_dest.

Detect pop in Navigation Component

In Navigation Component, how can one detect if fragment is brought to front from a pop event?
I go from A to B, now I close B using back key, it returns to A, now in A (in onViewCreated event) I want to detect it's coming from B.
If we're using a single NavController.
findNavController((R.id.nav_host_fragment)
.addOnDestinationChangedListener{ hostController, destination, _ ->
val push = currentBackStackSize < hostController.bacStack.size // else pop
// Then save current backstack size
}
This solution might not be always correct, but currently I can't think of an edge case. Please feel free to correct me.
Here is my solution.
In A, add a navigation argument with default value false (in the nav_graph.xml)
In B, add a navigation back to A. To handle back button pressed, add the following in onCreate()
requireActivity().onBackPressedDispatcher.addCallback {
val action = BDirections.actionBFragmentAFragment(true)
findNavController().navigate(action)
}
Now you can determine how A appears. Also, use popUpTo to handle circular logic properly. Let me know if you see any flaws in this approach.

Android navigate up the right graph when using NavController

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

Navigation Component can't pop to exit app

Using Android's Navigation Component, I have 3 fragments hosted by a single Activity. The launch fragment is a splash screen fragment (A), if the user is not logged in, I launch the login fragment (B), if they are logged in, I launch a list fragment (C).
So launch routes are either A->B->C or A->C.
When you land on B or C, pressing back should kill the app. The NavigationController though is instead backs up to A (I think, A's onActivityCreated is certainly called at which point it crashes which is probably unrelated).
Pop behaviors in the graph editor for A -> B seem to allow me to pop to different fragments but there doesn't seem to be an option to just kill the app.
Do I really need to override onBackPressed for this behavior and just kill the activity? Because this is easier without the NavigationController, usually I would just finish an activity as I start a new one.
Open text tab in Graph Editor to view xml code, find your two actions A -> B and A -> C and put tag: app:clearTask="true", it's should kill you app when user press back button.
Example:
<fragment
android:id="#+id/launcher_fragment"
android:name="com.example.LauncherFragment"
android:label="launcher_fragment">
<action
android:id="#+id/action_launcher_to_login"
app:destination="#id/login_fragment"
app:clearTask="true"/>
<action
android:id="#+id/action_launcher_to_list"
app:destination="#id/list_fragment"
app:clearTask="true" />
</fragment>

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