Fragment已经添加,DialogFragment?

12

我有一个DialogFragment,它显示得很好,但有时当我尝试显示它时,我会不断收到"IllegalStateException"错误。

以下是logcat:

java.lang.IllegalStateException: Fragment already added: SelectPlan04Dialog{fa768dc #7 }
    at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1893)
    at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:760)
    at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2595)
    at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2382)
    at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2337)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2244)
    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:702)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:192)
    at android.app.ActivityThread.main(ActivityThread.java:6679)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)]

以下是我调用对话框的代码

if (selectPlan04Dialog == null) {
    selectPlan04Dialog = new SelectPlan04Dialog();
}
if (!selectPlan04Dialog.isVisible() && !selectPlan04Dialog.isAdded()) {
    Bundle b = new Bundle();
    b.putSerializable("moduleApi", module);
    selectPlan04Dialog.setArguments(b);                
    selectPlan04Dialog.show(getCurrentActivity().getSupportFragmentManager(), "");
}
3个回答

21

片段事务是异步的。

很可能在片段事务执行之前您会有两个或更多对此代码的调用。 !selectPlan04Dialog.isVisible() & !selectPlan04Dialog.isAdded() 条件为 true,show() 安排了另一个片段事务稍后执行。

解决此问题的一些选项:

  • 每次创建新的对话框,不尝试重用旧的对话框
  • 使用片段管理器的调用将异步片段事务更改为同步 executePendingTransactions()

但是调用 executePendingTransactions 方法是否可行呢?我因为过多调用 show 方法而遇到了 ANR 问题。 - Nitin Mesta

8
 modalBottomSheet.show(supportFragmentManager.beginTransaction().remove(modalBottomSheet),ModalBottomSheet.TAG)

请问需要将内容翻译成哪种语言呢?

这似乎真的很有效。 - htafoya

2

这是我的解决方案,我尝试多次快速点击按钮以显示对话框片段。

try {
    FragmentManager fm = getSupportFragmentManager();
    Fragment oldFragment = fm.findFragmentByTag("wait_modal");
    
    if (oldFragment != null && oldFragment.isAdded())
        return;
    
    if (oldFragment == null && !please_wait_modal.isAdded() && !please_wait_modal.isVisible()) {
        fm.executePendingTransactions();
        please_wait_modal.show(fm,"wait_modal");
    }
} catch (Exception e) {
    e.printStackTrace();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接