11

I am trying to use the navigation controller right now. I want to move from LoginFragment to HomeFragment. In LoginFragment I use this code below to move to HomeFragment.

Navigation.findNavController(view).navigate(homeDestination)

However, when I tap the back button in the HomeFragment, it will go back to LoginFragment, I expect that when I tap the button it will close the app.

In old way, if I use activity instead of using Fragment, I usually do something like this to get that expected behaviour:

val intent = Intent(this,HomeActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK.or(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)

By using those flags, I use to get the expected behavior. But I don't how to implement the same behavior using the navigation controller.

Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
Alexa289
  • 8,089
  • 10
  • 74
  • 178
  • When you try to create new fragment from previous on, use replace in place of add. getSupportFragmentManager().beginTransaction() .replace(R.id.container_between, policies, Policies.TAG) .addToBackStack(Policies.TAG).commit(); – Sanwal Singh Feb 28 '19 at 05:45
  • @Shane - you don't directly use FragmentTransactions when using [Navigation](https://developer.android.com/topic/libraries/architecture/navigation). – ianhanniballake Feb 28 '19 at 05:47
  • @Shane I am using android navigation component not using fragment transaction anymore https://developer.android.com/topic/libraries/architecture/navigation/navigation-implementing – Alexa289 Feb 28 '19 at 05:47
  • Note that as per the [Principles of Navigation](https://developer.android.com/topic/libraries/architecture/navigation#fixed) and the [conditional navigation documentation](https://developer.android.com/topic/libraries/architecture/navigation/navigation-conditional), you shouldn't be using a login fragment as your start destination. – ianhanniballake Feb 28 '19 at 05:57

5 Answers5

18

Navigation offers a popUpTo and popUpToInclusive attributes for removing fragments from the back stack as part of a navigate() operation.

This can be set either in XML:

<!-- Add to your Navigation XML, then use navigate(R.id.go_home) -->
<action
  android:id="@+id/go_home"
  app:destination="@+id/home_fragment"
  app:popUpTo="@+id/destination_to_pop"
  app:popUpToInclusive="true"/>

Or set it programmatically:

NavOptions navOptions = new NavOptions.Builder()
    .setPopUpTo(R.id.destination_to_pop, true)
    .build();
Navigation.findNavController(view).navigate(homeDestination, navOptions)

You can also use the id of a <navigation> element as well.

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
3

I was following the answer of Ian but I had been having bad luck since I didn't know what the popUpTo would be.

So we have to use the id Of nav Graph there.

app:popUpTo="@+id/idOfNavGraph". //id of nav graph

<action
  android:id="@+id/go_home"
  app:destination="@+id/home_fragment"
  app:popUpTo="@+id/idOfNavGraph". //id of nav graph
  app:popUpToInclusive="true"/>
erluxman
  • 18,155
  • 20
  • 92
  • 126
0

I think this should do the trick.

NavController controller = Navigation.findNavController(view);
controller.popBackStack(R.id.fragmentLogin, true);
controller.navigate(homeDestination)
Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
  • 1
    While this works in some way, Navigation offers a built in `popUpTo` attribute do this as a single operation, without sending updates to `OnDestinationChangedListener` for that intermediate state. – ianhanniballake Feb 28 '19 at 05:59
  • Ya. That's the right idea. I saw your answer later I posted mine. Your one is perfect. Kudos! – Reaz Murshed Feb 28 '19 at 06:01
0

Try this

 val c = view.findNavController()
 c.popBackStack() // current fragment will be pop up from the stack
 c.navigate(DestinationFragmentID)
Shaon
  • 2,496
  • 26
  • 27
0

Obviously I'm late. Nonetheless I'd like to do my bit and expand Ian's answer. In app:popUpTo="@+id/destination_to_pop" the destination_to_pop really means the destination that you do not want to keep in the back stack. In your case, loging_fragment.

This way, when you navigate back from your HomeFragment the app will close since LoginFragment is not in the back stack anymore. You can find the related official documentation here.

Javi
  • 71
  • 1
  • 4