Search code examples
androidnavigationandroidxandroid-jetpackandroid-architecture-navigation

pop up to graph startDestination fragment for a global action - Android navigation components


I've a multi-graph navigation app and I'd like to switch between graphs by using a global action as defined in my root main_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/main_graph"
        app:startDestination="@id/loadingFragment">

    <include app:graph="@navigation/learn_graph" />

    <action
            android:id="@+id/action_global_learn_graph"
            app:destination="@id/learn_graph"
            app:launchSingleTop="true"
            />
</navigation>

Since I'm trying to switch between graphs, I'd like to clear the back stack from the fragments loaded by the source graph (main_graph) when navigating the global action to the destination graph (explore_graph). The expected behavior would be to navigate to the startDestination fragment of the destination graph keeping only that fragment in the backstack. For normal actions (actions in the same graph) I'm able to use popUpTo flag, how it's possible to get the same behavior for a global action?


Solution

  • After a lot of attemps, I found out a solution. The base idea is to pop up the backstack to the graph that "owns" the global action. In my case main_graph is the owner, so I did:

    <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/main_graph"
            app:startDestination="@id/loadingFragment">
    
        <include app:graph="@navigation/learn_graph" />
    
        <action
                android:id="@+id/action_global_learn_graph"
                app:destination="@id/learn_graph"
                app:popUpTo="@+id/main_graph"
                app:launchSingleTop="true" />
    
    </navigation>
    

    In addition, you have to set the app:launchSingleTop flag to true in order to make the instance of destination graph unique in your backstack

    You can also include app:popUpToInclusive="true" to indicate that the destination specified in app:popUpTo should also be removed from the back stack.