This question is tricky because of Jetpack Navigation's abysmal documentation on Conditional Navigation
which should explain this subject but fails to do so, but the answer is actually quite simple.
All you need is popUpTo
and popUpToInclusive
.
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation"
app:startDestination="@id/splash_graph"
tools:ignore="UnusedNavigation">
<navigation
android:id="@+id/splash_graph"
app:startDestination="@id/splash_fragment">
<action
android:id="@+id/splash_to_main_graph"
app:destination="@id/main_graph"
app:popUpTo="@id/splash_graph"
app:popUpToInclusive="true" />
<fragment
android:id="@+id/splash_fragment"
android:name="fqn.SplashFragment"
tools:layout="@layout/splash_fragment" />
</navigation>
<navigation
android:id="@+id/main_graph"
app:startDestination="@id/fragment_a">
<action
android:id="@+id/fragment_a_to_fragment_b"
app:destination="@id/fragment_b"
app:enterAnim="@anim/slide_in_from_left"
app:exitAnim="@anim/slide_out_to_right"
app:popEnterAnim="@anim/slide_out_to_left"
app:popExitAnim="@anim/slide_in_from_left" />
<action
android:id="@+id/fragment_b_to_fragment_c"
app:destination="@id/fragment_c"
app:enterAnim="@anim/slide_in_from_left"
app:exitAnim="@anim/slide_out_to_right"
app:popEnterAnim="@anim/slide_out_to_left"
app:popExitAnim="@anim/slide_in_from_left"
app:popUpTo="@id/fragment_b"
app:popUpToInclusive="true" />
<action
android:id="@+id/fragment_c_to_fragment_b"
app:destination="@id/fragment_b"
app:enterAnim="@anim/slide_in_from_left"
app:exitAnim="@anim/slide_out_to_right"
app:popEnterAnim="@anim/slide_out_to_left"
app:popExitAnim="@anim/slide_in_from_left"
app:popUpTo="@id/fragment_c"
app:popUpToInclusive="true" />
<fragment
android:id="@+id/fragment_a"
android:name="fqn.FragmentA"
tools:layout="@layout/fragment_a" />
<fragment
android:id="@+id/fragment_b"
android:name="fqn.FragmentB"
tools:layout="@layout/fragment_b" />
<fragment
android:id="@+id/fragment_c"
android:name="fqn.FragmentC"
tools:layout="@layout/fragment_c" />
</navigation>
</navigation>
And then it should be as simple as
// FragmentA
findNavController().navigate(R.id.fragment_a_to_fragment_b)
// FragmentB
findNavController().navigate(R.id.fragment_b_to_fragment_c)
// FragmentC
findNavController().navigate(R.id.fragment_c_to_fragment_b)
And if you want to go back to FragmentA from FragmentB or FragmentC, you can call findNavController().popBackStack()
.