9

I am using the new AndroidX navigation framework.

I have a few fragments all linked in a navigation chain.

FragmentA --> FragmentB --> FragmentC

FragmentC has a Cancel button that should send me up all the way back to FragmentA.

Should I do the following:
on FragmentC call the method:

 Navigation.findNavController(view).navigateUp();

then on FragmentB listen to some callback and using some passed parameter or argument trigger another navigateUp() function from FragmentB

or is there some method that will do the equivalent of navigateUpTwice()

Vasili Fedotov
  • 1,091
  • 14
  • 31

6 Answers6

20

What I ended up doing was

Navigation.findNavController(view).popBackStack(R.id.fragmant_a,false)
Vasili Fedotov
  • 1,091
  • 14
  • 31
4

In your navigation.xml file under the action that you have created to navigate to starting fragment (FragmentA in your case) add the following

<action
....
app:popUpTo="@id/fragmentA"
app:popUpToInclusive="false"/>

This will pop up all the fragments until FragmentA and will exclude FragmentA since popUpToInclusive is set to false.

Edit: The full form of your action under FragmentC tag of your navigation.xml file will be something similar to this:

<fragment
    android:id="@+id/FragmentC"
    android:name="com.yourdomain.FragmentC"
    android:label="FragmentC">
    <action
        android:id="@+id/action_fragmentC_to_fragmentA"
        app:destination="@id/fragmentA"
        app:popUpTo="@id/fragmentA"
        app:popUpToInclusive="false"/>
</fragment>
3

Try with this, it works for me.

findNavController().navigateUp()
findNavController().navigateUp()
vibroto
  • 188
  • 1
  • 5
2

You can set pop To FragmentA in your action from FragmentB --> FragmentC and when then you press back it goes to Fragment A instead of Fragment B

shakil.k
  • 1,623
  • 5
  • 17
  • 27
0

So I found myself in a situation where I had to navigateUp() twice, but with a twist: I could reach the view through several paths. Think of it like this:

Fragment A --> Fragment C --> Fragment D

Fragment B --> Fragment C --> Fragment D

In a normal situation, using the popTo xml attribute or the popBackStack() method would work. However it is unusable here. Fortunately, what you can do is:

val navController = NavHostFragment.findNavController(this)
navController.navigateUp()
navController.navigateUp

As other people have pointed out, this is absolutely not optimised performance-wise. In any situation where you can reach Fragment D through a single path, use popTo instead.

0

If you have situation like @flagg10ma in his answer, you can get info about previous destination and then use its id in the popBackStack() call. Like this:

NavController navController = NavHostFragment.findNavController(this);
NavBackStackEntry prevEntry = navController.getPreviousBackStackEntry();
if (prevEntry == null) {
  // There is no previous destination, so just pop once normally
  navController.popBackStack();
  return;
}
// Pop to previous destination and then pop that destination too (as we use inclusive=true)
navController.popBackStack(prevEntry.getDestination().getId(), true);
Robyer
  • 4,632
  • 2
  • 23
  • 21