Фрагмент уже добавлен, диалогфрагмент?

У меня есть диалоговое окно, которое отображается нормально, но когда я пытаюсь отобразить его, я продолжаю получать IllegalStateException

Ниже логотип

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(), "");
}

4 ответа

Фрагментные транзакции являются асинхронными.

Возможно, у вас есть два или более вызовов этого кода до выполнения транзакций фрагмента. !selectPlan04Dialog.isVisible() & !selectPlan04Dialog.isAdded() условие верно и show() планирует другую транзакцию фрагмента для выполнения позже.

Некоторые варианты исправления этого:

  • Создавайте новый диалог каждый раз и не пытайтесь повторно использовать старый
  • Изменить асинхронные транзакции фрагментов на синхронные с вызовом диспетчера фрагментов executePendingTransactions()
       modalBottomSheet.show(supportFragmentManager.beginTransaction().remove(modalBottomSheet),ModalBottomSheet.TAG)

Звонить так

Вот мое решение, я пытаюсь щелкнуть фрагмент диалога, нажав кнопку несколько раз и быстро.

              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();
        }

Laalto прав : Добавление транзакции фрагмента 、 удаление выполняется асинхронно, поэтому не работает, когда вы вызываете метод isAdded

Просто посмотрите на стек метода ошибки, он вызывается из основного обработчика и вызывает сбой FragmentManagerImpl.addFragment, это не вызов из вашего selectPlan04Dialog.show()

Так что учитесь из Руководства разработчика Android DialogFragment.

private void showDialog() {
    FragmentManager manager = getFragmentManager();
    if (manager != null) {
        FragmentTransaction ft = manager.beginTransaction();
        Fragment fragment = manager.findFragmentByTag(DIALOG_TAG);
        if (fragment != null) {
            ft.remove(fragment);
        }
        ft.addToBackStack(null);

        DialogFragment dialogFragment = createProfileDialog();
        dialogFragment.show(ft, DIALOG_TAG);
    }
}
  1. Вам не следует создавать фрагмент диалога как поле, он должен быть локальной переменной.
  2. Если вам нужен фрагмент диалога из другого метода, вы можете использовать тег фрагмента, чтобы запросить объект фрагмента.
  3. Если это уже добавленный фрагмент, вам следует сначала удалить его.