java.lang.IllegalStateException:片段已经为BottomSheetDialogFragment添加了异常

问题描述

为了显示BottomSheetDialogFragment中的最后一个状态,我尝试如下实现

* )活动:

    private var languageSelectorBsFragment: LanguageSelectorBsFragment? = null


    @OnClick(R.id.txt_imc_clip_language)
    fun onClickClipLanguage() {
        initLanguageBottomSheet()
        languageSelectorBsFragment?.show(supportFragmentManager,languageSelectorBsFragment!!.tag)
    }

    private fun initLanguageBottomSheet() {
        if (languageSelectorBsFragment == null) {
           languageSelectorBsFragment = LanguageSelectorBsFragment.newInstance(LanguageSelectorBsFragment.TYPE_USER)
        }
    }

* )BottomSheetDialogFragment

class LanguageSelectorBsFragment : BottomSheetDialogFragment() {
   var lastSelectedLanguageId: String?;
   var userInputInEditText: String?;
}

因此,只有一个BottomSheetDialogFragment实例,我需要保留上一次打开底部工作表时用户与之交互的许多其他变量的引用。

通过执行上述步骤,我可以达到我们的要求,但有几次它是随机崩溃的,我无法找到根本原因。

* )例外:

Fatal Exception: java.lang.IllegalStateException: Fragment already added: LanguageSelectorBsFragment{2b446ae} (8fe75d96-932d-47eb-97af-128319431a55)}
       at androidx.fragment.app.FragmentStore.addFragment(FragmentStore.java:67)
       at androidx.fragment.app.FragmentManager.addFragment(FragmentManager.java:1563)
       at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:405)
       at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167)
       at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990)
       at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945)
       at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847)
       at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
       at android.os.Handler.handleCallback(Handler.java:751)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:154)
       at android.app.ActivityThread.main(ActivityThread.java:6351)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:896)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:786)

我知道已经存在许多例外情况完全相同的问题,而我能想到的最接近的问题是this

此外,我必须使用BottomSheetDialogFragment,并且不能使用“ Persistent Bottom Sheet”。我非常希望Android为“模态底部表”提供显示隐藏功能,并且不要在每次关闭时都关闭它。

* )问题:

1)如何防止此崩溃?

2)有没有一种方法可以“隐藏”模态底部工作表而无需“关闭”?

解决方法

我自己遇到了这个问题,这是我处理问题的一种方式,也许会对您有所帮助。
我必须在该对话框顶部显示的BottomSheetDialogFragment的整个生命周期中保持Fragment的状态。

所以基本上,我创建了一个共享的ViewModel,该片段有一个实例,每个显示的对话框都有一个实例。
这样,您每次显示对话框时都可以拥有相同的数据。
here显示了简单的实现。

这样,您无需在活动中将实例保存到对话框中,只需通过ViewModel访问对话框中的数据即可。它真的很干净而且易于维护。