简体   繁体   中英

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

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) - ie, pop back to fragmentB , but don't pop fragmentB itself.

You can use the class SingleLiveEvent to retain the previous state since it emits the data only once whenever required.

learn more about SingleLiveEvent:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM