Фрагмент уже добавлен IllegalStateException - PullRequest
53 голосов
/ 06 июня 2011

Я использую этот метод в своем контейнере Activity, чтобы показать BFrag

public void showBFrag()
{
    // Start a new FragmentTransaction
    FragmentTransaction fragmentTransaction = mFragmentMgr.beginTransaction();

    if(mBFrag.isAdded())
    {
        Log.d(LOG_TAG, "Show() BFrag");
        fragmentTransaction.show(mBFrag);   
    }
    else
    {
        Log.d(LOG_TAG, "Replacing AFrag -> BFrag");
        fragmentTransaction.replace(R.id.operation_fragments_frame, mBFrag);
    }

    // Keep the transaction in the back stack so it will be reversed when backbutton is pressed
    fragmentTransaction.addToBackStack(null);

    // Commit transaction
    fragmentTransaction.commit();        
}

Я вызываю его из моего контейнера Activity;в первый раз:

  • попадает в оператор else и mBFrag заменяет mAFrag.

Затем я нажимаю кнопку возврата:

  • , и операция переворачивается (отображается mAFrag, но .. mBFrag удален?).

Затем я снова иду вперед, вызывая showBFrag () из той же операции:

  • , и он снова попадает в оператор else.(поэтому я могу сделать вывод, что mBFrag НЕ ДОБАВЛЕНО)
  • , но я получил фрагмент, уже добавленный IllegalStateException ... (так почему он не попал в оператор if?)1023 *

Итак:

  1. Почему метод isAdded () не возвращает TRUE, если я получаю фрагмент, уже добавленный IllegalStateException ??
  2. Полностью ли операция popBackStack удаляет ранее добавленные фрагменты?
  3. Какое поведение я неправильно понимаю?

РЕДАКТИРОВАТЬ: Вот полная информация об исключении.

06-07 12:08:32.730: ERROR/AndroidRuntime(8576): java.lang.IllegalStateException: Fragment already added: BFrag{40b28158 id=0x7f0c0085}
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.doAddOp(BackStackRecord.java:322)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.replace(BackStackRecord.java:360)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.replace(BackStackRecord.java:352)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at myPackageName.containerActivity.showBFrag() // This line: "fragmentTransaction.replace(R.id.operation_fragments_frame, mBFrag);"

Ответы [ 11 ]

41 голосов
/ 07 июня 2011

Наконец, мой обходной путь состоял в том, чтобы выполнить remove () предыдущего фрагмента и добавить () новый.Хотя это то, для чего предназначен метод replace () ...

Но я все еще догадываюсь, почему метод replace () не работал нормально в этом случае ... действительно странноЯ хочу отказаться от этого, потому что я что-то неправильно понимаю или делаю что-то не так.

12 голосов
/ 06 июня 2011

Если состояние действия уже сохранено, его больше не безопасно вызывать. Вы должны позвонить commitAllowingStateLoss() вместо. Надеюсь, это поможет!

Редактировать: хорошо. Я более внимательно изучил вашу проблему, проблема в том, что вы пытаетесь добавить уже добавленный фрагмент. Даже если вы используете замену или удаление вызовов, вы не можете сделать это. Единственное, что я нашел, - это создание нового экземпляра фрагмента и добавление его каждый раз. После того как вы удалите или замените фрагмент, лучше отказаться от всех ссылок на него, чтобы ГК мог позаботиться об этом.

8 голосов
/ 16 февраля 2012

Вероятно, не связано с этой проблемой напрямую, но я также заметил, что установка перехода к FragmentTransaction вызовет исключение IllegalStateException, в то время как установка перехода не будет.

Вот ошибка для этой проблемы: http://code.google.com/p/android/issues/detail?id=25598

1 голос
/ 09 июня 2015

Я использовал это:

if (getFragmentManager().findFragmentByTag(newFragment.getClass().getName()) != null) {
   transaction.remove(newFragment);
 }

и добавил фрагмент с

MyFragment frag = new MyFragment(); 
transaction.add(R.id.container, frag, MyFragment.class.getName())

MyFragment.class.getName() означает tag

1 голос
/ 02 мая 2015

попробуйте это после fragTransection.replace ()

fragmentTransection.addToBackStack(null);
fragmentTransection.commitAllowingStateLoss();
1 голос
/ 06 июня 2014

Проверьте, был ли фрагмент уже добавлен или нет, используя методgment .isAdded () Замените или добавьте фрагмент соответствующим образом.

0 голосов
/ 15 ноября 2017

если (mFragment.isAdded ()) { вернуть; // или вернуть false / true, исходя из того, откуда вы звоните }

0 голосов
/ 17 августа 2016

Удаление setOffscreenPageLimit из Viewpager решило мою проблему. Спасибо.

0 голосов
/ 29 сентября 2014

Решил это, просматривая мои фрагменты и проверяя, является ли isAdded () истиной, затем удаляя этот фрагмент. Подробнее здесь.

0 голосов
/ 04 января 2014

Этот код работает нормально для меня. попробуйте это

((MiActivity)getActivity()).addAccount = new AddAccount();
((MiActivity)getActivity()).addAccount.setArguments(params);
fragmentManager = getActivity().getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container((MiActivity)getActivity()).addAccount);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
...