使用Backstack保留片段导航状态

时间:2020-06-04 11:56:44

标签: android android-fragments

我试图用Activity中的Fragments来处理状态和导航问题,但是在尝试正确保留导航状态时感到困惑。说我有这种导航路径:

Activity
   |
FragA
   |_____________
   |     |      |
FragB  FragC  FragD
         |
       FragE

FragA是创建“活动”时显示的初始片段。您可以从FragA导航到FragB / FragC / FragD。您可以从FragC导航到FragE。在每个级别上,片段都会添加到后台,因此路径可能是例如FragA> FragD或FragA> FragC> FragE。

我正在使用此代码设置第一个片段:

private fun setFragment(fragment: Fragment) {
    fragmentManager
        .beginTransaction()
        .replace(R.id.container, fragment)
        .commit()
}

此代码设置下一个片段:

fun pushFragment(fragment: Fragment)
    fragmentManager
        .beginTransaction()
        .replace(R.id.container, fragment)
        .addToBackStack(null)
        .commit()
}

为了处理活动何时重新开始,我使用onSaveInstanceStateonRestoreInstanceState保存片段的当前位置。

在我的onCreate中,我基本上是这样做的:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity)

        if (savedInstanceState == null) {
            displayFragment(FragA)
        }
    }

private fun displayFragment(page: String) {
        currentFragment = page
        when (page) {
            FRAG_A -> setFragment(FragA())
            FRAG_B -> pushFragment(FragB())
            FRAG_C -> pushFragment(FragC())
            FRAG_D -> pushFragment(FragD())
            FRAG_E -> pushFragment(FragE())
        }
    }

例如,当我当前在FragC上时,一切正常。我重新启动了活动,并在重新创建活动后按预期返回了FragC,但是一旦尝试导航至FragE,我就会被IllegalStateException击中。

Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

因此,在重新创建活动之后,如果我尝试对某个片段事务进行commit(),则该异常会崩溃。为什么?我的理解是,在活动重新启动之前调用onSaveInstanceState时状态已经保存,为什么在重新创建活动后提交事务是非法的?

我已经读到某些解决方案使用commitAllowingStateLoss()代替commit(),但是我不太了解使用它代替其他方法的效果。

当我使用commitAllowingStateLoss()并打印日志时,我得到了:

E/Debug: OnCreate Activity
E/Debug: Set fragment: FragA
E/Debug: Push fragment: FragC

<Restarting the activity>

E/Debug: onSaveInstanceState called
E/Debug: OnCreate Activity
E/Debug: onRestoreInstanceState called

<Navigating to FragE>

E/Debug: Push fragment: Frag E
E/Debug: Push fragment: Frag E

那里发生了什么?日志显示好像我的用于设置FragE的片段事务被调用了两次,但是当我在应用程序上来回导航时,backstack似乎没有任何问题,但是每次我推送一个新片段时,日志都会打印两次。

这是处理片段导航的正确方法吗?

0 个答案:

没有答案