Our app uses the OpenId AppAuth lib for login. The initial fragment and some info-dialogs are contained in nav_graph_login
. After successful login, the user is forwarded to a dashboard, which is inside nav_graph_main
, using the app:popUpTo=@id/nav_graph_login
and app:popUpToInclusive="true"
to remove the login fragments from the backstack. So, tapping the "back" button on the dashboard closes the app. Works well!
From the dashboard, the user can navigate to different "details" fragments.
However, if we deep link to one of the details fragments, the nav_graph_login
remains in the backstack. Clicking the "back" button on the dashboard will show the login screen. This is unintended. I guess this is caused by this from here:
As with explicit deep linking, when nesting graphs, the start destination from each level of nesting—that is, the start destination from each element in the hierarchy—is also added to the stack.
Does anyone have an idea, how to avoid this behavior on deep links?
We handle deep links in the MainActivity
class MainActivity {
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
// there is more logic here, but for the sake of this post, I keep it simple
navController.handleDeepLink(intent)
}
}
main_activity.xml
<androidx.constraintlayout.widget.ConstraintLayout
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:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph_login" />
</androidx.constraintlayout.widget.ConstraintLayout>
nav_graph_login:
<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/welcomeScreenFragment">
<include app:graph="@navigation/nav_graph_main" />
<fragment
android:id="@+id/welcomeScreenFragment"
android:name="my.app.WelcomeScreenFragment"
android:label="WelcomeScreenFragment">
<action
android:id="@id/action_dashboard"
app:destination="@id/nav_graph_main"
app:popUpTo="@id/nav_graph_login"
app:popUpToInclusive="true" />
</fragment>
</navigation>
nav_graph_main:
<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_main"
app:startDestination="@id/dashboard">
<action
android:id="@+id/action_dashboard"
app:destination="@id/nav_graph_main"
app:popUpTo="@id/nav_graph"
app:popUpToInclusive="true" />
<fragment
android:id="@+id/dashboard"
android:name="my.app.Dashboard">
<action
android:id="@+id/action_dashboardFragment_to_details1Fragment"
app:destination="@id/details1" />
</fragment>
<fragment
android:id="@+id/details1"
android:name="my.app.Details1Fragment">
<deepLink
android:id="@+id/deepLinkToDetails1"
app:uri="a-host.net/details/{id}" />
</fragment>
</navigation>
As discussed here, navController.handleDeepLink(intent)
is responsible for restarting the Activity. The linked thread also contains possible solutions.