Search code examples
androidkotlinsharedpreferencesandroid-navigation-graph

Fragment is not getting popped using navigation graph


I am building an app where first time it opens fragment1 to get user details and once user forwards to next fragment2, I am saving the details and setting a boolean variable isUserRegistered to true in SharedPreferences so that when the user opens the app next time, he/she will be directly taken to the fragment2. I am using using navigation graph to handle these things.

Following is the code:

//declared at the top in onCreateView() of fragment
val prefs = appContext!!.getSharedPreferences("expense_prefs", Context.MODE_PRIVATE)

Once user clicks Continue button, following actions are defined (only showing the relevant code)

val editor = prefs.edit()
editor.putBoolean("isUserRegistered", true)
editor.apply()
findNavController().navigate(R.id.action_getStartedFragment_to_homeFragment)

and in order to redirect user when he/she visits app the next time, I have written following code:

//in the same onCreateView() of fragment1
val isUserRegistered = prefs.getBoolean("isUserRegistered", false)
if (isUserRegistered)
    findNavController().navigate(R.id.action_getStartedFragment_to_homeFragment)

and following is my navigation file in which I have also added app:popUpToInclusive="true" in both of the navigations.

<?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"
    app:startDestination="@id/getStartedFragment">
    <fragment
        android:id="@+id/getStartedFragment"
        android:name="net.softglobe.expensemanager.GetStartedFragment"
        android:label="fragment_get_started"
        tools:layout="@layout/fragment_get_started" >
        <action
            android:id="@+id/action_getStartedFragment_to_homeFragment"
            app:destination="@id/homeFragment"
            app:popUpToInclusive="true" />
    </fragment>
    <fragment
        android:id="@+id/homeFragment"
        android:name="net.softglobe.expensemanager.HomeFragment"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home" >
        <action
            android:id="@+id/action_homeFragment_to_getStartedFragment2"
            app:destination="@id/getStartedFragment"
            app:popUpToInclusive="true" />
    </fragment>
</navigation>

Still, when user navigates from fragment1 to fragment2, the previous fragment is not getting popped out. And when user presses back button from fragment2, the compiler is coming again on fragment1 and because of that navigation code piece (shown above) it is navigating user to fragment2, as isUserRegistered is true. How can I solve the issue?


Solution

  • Take a look at this article

    To pop destinations when navigating from one destination to another, add an app:popUpTo attribute to the associated element. app:popUpTo tells the Navigation library to pop some destinations off of the back stack as part of the call to navigate(). The attribute value is the ID of the most recent destination that should remain on the stack.

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

    You're not providing the needed fragment to where you should have been popped, something like app:popUpTo="@id/getStartedFragment"