Search code examples
androidkotlinandroid-jetpackandroid-architecture-navigationandroid-jetpack-navigation

Prevent destroying (or restore state) of Fragment B when navigating back from D - Navigation Component


I have fragments: A, B, C, D. I navigate A -> B . Fragment B gets and saves state from arguments. Then I navigate B -> C. And then C -> D. When I call two times findNavController().popBackStack() I get correct behavior: D -> B and B still has correct state. It works because fragment B has never been destroyed, just its view. And then view is recreated when coming back. But calling two times popBackStack() isn't recommended action. We should instead use the action with app:popUpTo and app:popUpToInclusive="true":

<action
    android:id="@+id/action_fragmentD_to_fragmentB"
    app:destination="@id/fragmentB"
    app:popUpTo="@+id/fragmentB"
    app:popUpToInclusive="true" />

But it forces fragment B to be destroyed completely and then recreated. Bu with no previous state.

In other words I want to achieve the same behavior as with Activities when used FLAG_ACTIVITY_CLEAR_TOP + FLAG_ACTIVITY_SINGLE_TOP: https://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP


Solution

  • There's no requirement to have an app:destination="@id/fragmentB" on an action if you don't want to navigate to a new instance of fragmentB (since that's what app:destination does). Therefore you can use:

    <action
        android:id="@+id/action_fragmentD_to_fragmentB"
        app:popUpTo="@+id/fragmentB" />
    

    This is identical to calling popBackStack(R.id.fragmentB, false) - i.e., pop back to fragmentB, but don't pop fragmentB itself.