Search code examples
androidkotlinandroid-jetpackandroid-architecture-navigation

android-clear fragment after navigate in navigation component


have some problem here.

let's say I have 3 fragment A-B-C. First i navigate from fragment A to B. Then from fragment B i want to navigate to fragment C and clear fragment B from stack. I need to clear it while navigate because i need to make sure the stack become A-C when the user in fragment C, if user click back, user will back to fragment A and there's also a button in fragment C to navigate to fragment B

please help me on this, need some advise to do this or if there any other solution please share it here.

Thanks


Solution

  • 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().