19

In my app i have used one activity and four fragment . In this app I used navigation component. My fragment loading sequence is A->B->C->D

In fragment D On device back button press I want to remove fragment C from backstack so that fragment B can open. Any one suggest me how can I do Thank you in advance

this is my navigation_graph.xml

<?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_graph"

    app:startDestination="@id/firstFragment"
    >
    <fragment
        android:id="@+id/firstFragment"
        android:name="com.education.javaprogramming.fragments.MainFragment"
        android:label="fragment_first"
        tools:layout="@layout/activity_main" >

        <action
            android:id="@+id/action_firstFragment_to_displayList1Fragment"
            app:destination="@id/displayList1Fragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"
            />
        <action
            android:id="@+id/action_firstFragment_to_displayList2Fragment"
            app:destination="@id/displayList2Fragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
        <action
            android:id="@+id/action_firstFragment_to_helpFragment"
            app:destination="@id/helpFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"
            />
        <action
            android:id="@+id/action_firstFragment_to_quizzFragment"
            app:destination="@id/quizzFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
    </fragment>
    <fragment
        android:id="@+id/displayList1Fragment"
        android:name="com.education.javaprogramming.fragments.DisplayList1Fragment"
        android:label="fragment_display_list1"
        tools:layout="@layout/fragment_display_list1"

        >
        <argument
            android:name="position1"
            app:argType="integer" />
        <action
            android:id="@+id/action_displayList1Fragment_to_firstFragment"
            app:destination="@id/firstFragment" />
        <argument
            android:name="name"
            app:argType="string" />
        <action
            android:id="@+id/action_displayList1Fragment_to_displayList2Fragment"
            app:destination="@id/displayList2Fragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"


            />
    </fragment>
    <fragment
        android:id="@+id/displayList2Fragment"
        android:name="com.education.javaprogramming.fragments.DisplayList2Fragment"
        android:label="fragment_display_list2"
        tools:layout="@layout/fragment_display_list2" >
        <action
            android:id="@+id/action_displayList2Fragment_to_displayList1Fragment"
            app:destination="@id/displayList1Fragment"

            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"
            />
        <action
            android:id="@+id/action_displayList2Fragment_to_firstFragment"
            app:destination="@id/firstFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
        <argument
            android:name="position1"
            app:argType="integer" />
        <argument
            android:name="position2"
            app:argType="integer" />
        <argument
            android:name="name"
            app:argType="string" />
        <action
            android:id="@+id/action_displayList2Fragment_to_displayListInDeFragment"
            app:destination="@id/displayListInDeFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
    </fragment>
    <fragment
        android:id="@+id/displayListInDeFragment"
        android:name="com.education.javaprogramming.fragments.DisplayListInDeFragment"
        android:label="fragment_display_list_in_de"
        tools:layout="@layout/fragment_display_list_in_de" >
        <action
            android:id="@+id/action_displayListInDeFragment_to_displayList2Fragment"
            app:destination="@id/displayList2Fragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
        <argument
            android:name="position1"
            app:argType="integer" />
        <argument
            android:name="position2"
            app:argType="integer" />
        <argument
            android:name="position3"
            app:argType="integer" />
        <argument
            android:name="name"
            app:argType="string" />
    </fragment>
    <fragment
        android:id="@+id/helpFragment"
        android:name="com.education.javaprogramming.fragments.HelpFragment"
        android:label="fragment_help"
        tools:layout="@layout/fragment_help" >
        <action
            android:id="@+id/action_helpFragment_to_firstFragment"
            app:destination="@id/firstFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"
            />
        <argument
            android:name="position1"
            app:argType="integer" />
        <argument
            android:name="name"
            app:argType="string" />
        <action
            android:id="@+id/action_helpFragment_to_aboutFragment"
            app:destination="@id/aboutFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
    </fragment>
    <fragment
        android:id="@+id/aboutFragment"
        android:name="com.education.javaprogramming.fragments.AboutFragment"
        android:label="fragment_about"
        tools:layout="@layout/fragment_about" >
        <action
            android:id="@+id/action_aboutFragment_to_helpFragment"
            app:destination="@id/helpFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"
            />
    </fragment>
    <fragment
        android:id="@+id/quizzFragment"
        android:name="com.education.javaprogramming.fragments.QuizzFragment"
        android:label="fragment_quizz"
        tools:layout="@layout/fragment_quizz" >
        <action
            android:id="@+id/action_quizzFragment_to_firstFragment"
            app:destination="@id/firstFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
        <action
            android:id="@+id/action_quizzFragment_to_displayExamFragment"
            app:destination="@id/displayExamFragment" />
    </fragment>
    <fragment
        android:id="@+id/displayExamFragment"
        android:name="com.education.javaprogramming.fragments.DisplayExamFragment"
        android:label="fragment_display_exam"
        tools:layout="@layout/fragment_display_exam" >
        <action
            android:id="@+id/action_displayExamFragment_to_quizzFragment"
            app:destination="@id/quizzFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
        <argument
            android:name="position1"
            app:argType="integer" />
        <action
            android:id="@+id/action_displayExamFragment_to_resultFragment"
            app:destination="@id/resultFragment" />
    </fragment>
    <fragment
        android:id="@+id/resultFragment"
        android:name="com.education.javaprogramming.fragments.ResultFragment"
        android:label="fragment_result"
        tools:layout="@layout/fragment_result" >
        <action

            android:id="@+id/action_resultFragment_to_quizzFragment"
            app:destination="@id/quizzFragment" />
        <argument android:name="givenAnswers"
            app:argType="reference"
            />
        <argument android:name="actualAnswers"
            app:argType="reference"
            />
    </fragment>


</navigation>
Sushant Bansode
  • 203
  • 1
  • 2
  • 5

6 Answers6

12

You can use navController.popBackStack(int destinationId,bool inclusive) method, (please mind boolean value)

Attempts to pop the controller's back stack back to a specific destination. eg.

navController.popBackStack(R.id.dest_id_of_B, true)
Bharatesh
  • 8,943
  • 3
  • 38
  • 67
10

You should use

      app:popUpTo="@id/id_of_c_fragment" 
      app:popUpToInclusive="true"
      app:popUpTo="@id/id_of_d_fragment"
      app:popUpToInclusive="true"

in navigation graph in action scope.

khamidjon
  • 131
  • 2
  • 6
  • 3
    Worked for me exactly as I needed it, and I believe it's much simpler like this, putting it in the xml, than doing it programmatically – FabioR Nov 27 '20 at 16:42
3

In fragment D, if you want to back to fragment B (remove fragment C), you can use:

Navigation.findNavController(requireView()).popBackStack(
    R.id.id_of_fragment_C, true)

id_of_fragment_C is the id of fragment which you want to skip.

Ralf
  • 16,086
  • 4
  • 44
  • 68
1

Well i had the same problem but y solved like this

    <action
        android:id="@+id/id_action"
        app:destination="@id/fragment_D"
        app:launchSingleTop="true"
        app:popUpTo="@id/fragment_B"
        app:popUpToInclusive="true" />
Dharman
  • 30,962
  • 25
  • 85
  • 135
0

I had need of a similar Scenario where
A user on the Verification Screen (A) has to Go through Instruction Screen (B) and Upload Screen (C).

Here, are the desired navigation journeys

  • Forward navigation A > B > C
  • Back Navigation A < C
  • Navigation upon successful upload on Fragment-C A < C

Hence to achieve this, here are the navigation actions that I had to write.

To navigate A > B, simple navigation
<action
android:id="@+id/action_verification_to_upload_info"
app:destination="@id/navigation_upload_info" />
To navigate B > C

navigation with pop back upto & inclusive B, resulting landing on A.

<action android:id="@+id/action_id_upload_info_to_verification_upload"
app:popUpTo="@id/action_verification_to_upload_info"
app:popUpToInclusive="true"
app:destination="@id/navigation_id_verification_upload" />

Do notice that app:popUpTo has the value of navID for Fragment B and app:popUpToInclusive="true"

This worked for me like a charm!

sud007
  • 5,824
  • 4
  • 56
  • 63
0

If you know the destination you have to go back to, i would recommend you @Bharatesh 's answer;

Or @sudo007 's answer if you prefer the XML way.

If you don't know from where your user is navigating from, to current screen as there were more than one paths to current destination, try this:

button.setOnClickListener {
        val navController= it.findNavController()
        navController.previousBackStackEntry?.let { backEntry -> navController.popBackStack(backEntry.destination.id,true) }
    }

This will dynamically retrieve your previous back stack entry and and pop both current and previous destinations from your back stack.

true here is making it include the written destination to be popped from backStack.

In case lambda expression is difficult to understand, try code below:

val navController = it.findNavController()
    val prevId = navController.previousBackStackEntry?.destination?.id
    if (prevId != null) {
        navController.popBackStack(prevId, true)
    }
Johny Gates
  • 75
  • 1
  • 9