androiduinavigationcontrollerback-stackandroid-deep-linknavigation-architecture

Adding fragment manually into the backstack in Navigation Architecture Component


I am having 4 fragments in Navigation Graph, Named A, B, C, D, On which i am getting some data from the user.

When i an in a normal flow (A->B->C->D) and press back button everything(back-stack) working fine.

But i have a case in which i have and edit information flow, Suppose user left the form on Fragment D so when user come again on the screen, i have to navigate the user on the same screen i.e. Fragment D. I achieved it via Deep-link.

Now the problem is in the above case there will be no fragment in the Stack other than fragment D. But i need when user press back button it should navigate to Fragment C to Fragment B to Fragment A .

Means i want other Fragments(A,B,C) to add in the back-stack. Can we do the same, if yes, how?

===Here is the code===

my_navigation_graph.xml.

<fragment
    android:id="@+id/aFragment"
    android:name="in.demo.project.AFragment"
    android:label="AFragment"
    tools:layout="@layout/fragment_a_layout">
    <deepLink
        android:id="@+id/deepLink"
        android:autoVerify="true"
        app:uri="demo://editflow?is_for_edit={is_for_edit}&amp;step={step}" />
    <argument
        android:name="is_for_edit"
        android:defaultValue="false"
        app:argType="boolean" />
    <argument
        android:name="step"
        android:defaultValue="2"
        app:argType="string" />

    <action
        android:id="@+id/action_aFragment_to_bFragment"
        app:destination="@id/bFragment"/>

    <action
        android:id="@+id/action_aFragment_to_cFragment"
        app:destination="@id/cFragment"/>
    <action
        android:id="@+id/action_aFragment_to_dFragment"
        app:destination="@id/dFragment"/>


<fragment
    android:id="@+id/bFragment"
    android:name="in.demo.project.BFragment"
    android:label="BFragment"
    tools:layout="@layout/fragment_b_layout">
    <action
        android:id="@+id/action_bFragment_to_cFragment"
        app:destination="@id/cFragment" />
</fragment>

<fragment
    android:id="@+id/cFragment"
    android:name="in.demo.project.CFragment"
    android:label="CFragment"
    tools:layout="@layout/fragment_c_layout">

    <action
        android:id="@+id/action_cFragment_to_dFragment"
        app:destination="@id/dFragment" />

</fragment>
<fragment
    android:id="@+id/dFragment"
    android:name="in.demo.project.DFragment"
    android:label="DFragment"
    tools:layout="@layout/fragment_d_layout">
    
</fragment>

Navigating through.

findNavController().navigate(AFragmentDirections.actionAFragmentToBFragment())

Inside AFragment i am redirecting to other fragment, assuming that creating deep-link to every fragment is not good practice.

This code is in onCreate() Method of AFragment

arguments?.let {
            if (AFragmentArgs.fromBundle(it).isForEdit) {
                redirectionForEdit(AFragmentArgs.fromBundle(it).step)
            } 
        }

and a function for redirection

  private fun redirectionForEdit(step: String) {
        when (step) {
            "2" ->
                findNavController().navigate(AFragmentDirections.actionAFragmentToBFragment())
            "3" ->
                findNavController().navigate(AFragmentDirections.actionAFragmentToCFragment())
            "4" ->
                findNavController().navigate(AFragmentDirections.actionAFragmentToDFragment())  

        }

    }

Now if i get 4 in the step it'll redirect to DFragment, so the stack would be A->D, but i want B & D into the stack too (A->B->C->D).


Solution

  • For this please refer handling custom back navigation under navigation components

    OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
            @Override
            public void handleOnBackPressed() {
                // Handle the back button event
            }
        };
        requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);