4

I've met a problem with the back stack while starting the app from a deep link (via notification).

The general idea is that I have 3 fragments (A, B, C). The A screen works as splash screen, so I've put a popUpTo and popUpToInclusive to the action, so I can never see back to it again. My deep link destination is fragment C. To achieve the proper back stack I've merged B and C into nested navigation. Unfortunately, when I press Back button in fragment B the app is showing fragment A. My guess this is because the action from A to B with popUpTo was never called when the app was started from the deep link itself. My question is: how to avoid going back from B to A in this particular scenario?

Thanks in advance! I attach the sample code:

<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/nav_graph"
    app:startDestination="@id/splashFragment">

    <fragment
        android:id="@+id/A"
        android:name="A"
        android:label="A" >
        <action
            android:id="@+id/action_A_to_B"
            app:destination="@id/B"
            app:popUpTo="@id/A"
            app:popUpToInclusive="true" />
    </fragment>
    <navigation android:id="@+id/nested_nav"
        app:startDestination="@id/B">
        <fragment
            android:id="@+id/B"
            android:name="B"
            android:label="B">
            <action
                android:id="@+id/action_B_to_C"
                app:destination="@id/C" />
        </fragment>
        <fragment
            android:id="@+id/C"
            android:name="C"
            android:label="C">
        </fragment>
    </navigation>
</navigation>

And my DeepLinkBuilder (nothing special, same as the docs)

NavDeepLinkBuilder(requireContext())
    .setGraph(R.navigation.nav_graph)
    .setDestination(R.id.userProfileFragment)
    .createPendingIntent()
    .send()
shurrok
  • 795
  • 2
  • 13
  • 43

1 Answers1

0

You have set the navGraph that contain the splash screen as the default startDestination which lead to show it when you press back button from the nested navGraph , I think the easiest solution is to do the following : First edit you nav file to have only one navigation like :

<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/nav_graph"
    app:startDestination="@id/splashFragment">

    <fragment
        android:id="@+id/A"
        android:name="A"
        android:label="A" >
        <action
            android:id="@+id/action_A_to_B"
            app:destination="@id/B"
            app:popUpTo="@id/A"
            app:popUpToInclusive="true" />
    </fragment>
    <fragment
            android:id="@+id/B"
            android:name="B"
            android:label="B">
            <action
                android:id="@+id/action_B_to_C"
                app:destination="@id/C" />
        </fragment>
        <fragment
            android:id="@+id/C"
            android:name="C"
            android:label="C">
        </fragment>
</navigation>

Secondly set a listener to navController to listen when a destination change occur , like this :

yourNavController.setOnDestinationChangedListener(this);

override onDestinationChangedListener() method and check if the fragment which about to get showed is A , then finish the app like :

@override 
public void onDestinationChanged(NavController controller, NavDestination destination, Bundle arguments){
if(destination.getId()==R.id.splashFragmentId){
finish();
}
}
Mustafa Ibrahim
  • 557
  • 3
  • 8