DialogFragment 上的 commitAllowingStateLoss

commitAllowingStateLoss on DialogFragment

我有 IllegalStateException 显示 DialogFragment :

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

我知道为什么会这样,但我想使用 commitAllowingStateLoss 通过覆盖 DialogFragment show 函数来显示对话框:

public void show(FragmentManager manager, String tag) {
    mDismissed = false;
    mShownByMe = true;
    FragmentTransaction ft = manager.beginTransaction();
    ft.add(this, tag);
    ft.commit(); //replace it by commitAllowingStateLoss
}

但我无法访问 mDismissedmShownByMe 变量,我如何访问这些变量以像父级那样修改它们。

我认为为了防止在 DialogFragment 上抛出 IllegalStateException 可能更好地使用:

 YourDialogFragment dialogFragment = new YourDialogFragment();
 fragmentManager.beginTransaction().add(dialogFragment, YourDialogFragment.TAG_FRAGMENT).commitAllowingStateLoss();

而不是在 DialogFragment 上使用 show()

如果您的 DialogFragment 没有要保存的状态,则有关 commitAllowingStateLoss 的解决方案有效,否则它们将像函数名所说的那样丢失。但我认为在大多数情况下我们有状态要保存,这是 DialogFragment 的主要好处:Android 重新创建它并自动维护它的状态。

更好的解决方案是检查重建过程是否完成,如果没有则 return 给调用者,它是 Activity 或片段 Activity,它应该调用标记它并稍后在其 onPostResume() 或 onResumeFragments() 回调中再次调用 show 函数,我们可以确保重新创建所有片段。

这是 DialogFragment 的子类中重写的 show():

public boolean show(FragmentManager fragmentManager) {
   if (fragmentManager.isStateSaved()) return false;
   show(fragmentManager, tagName);
   return true;
}

原始对话片段

public void show(FragmentManager manager, String tag) {
    mDismissed = false;
    mShownByMe = true;
    FragmentTransaction ft = manager.beginTransaction();
    ft.add(this, tag);
    ft.commit(); //replace it by commitAllowingStateLoss
}

我不知道 mDismissedmShownByMe 变量的用途,所以如果覆盖 DialogFragment 的 show(FragmentManager, String) 方法应该会更好,它对我来说很好用

override fun show(manager: FragmentManager?, tag: String?) {
    if (manager?.isDestroyed == false && !manager.isStateSaved) {
      super.show(manager, tag)
    }
  }

isStateSaved 可从 appcompat >= 26.0.0 或 androidx