Подтвердить что ты не робот

Фрагмент уже добавлен IllegalStateException

Я использую этот метод для своего контейнера 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() из той же Activity:

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

Итак:

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

EDIT: Вот полная информация об исключении.

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);"
4b9b3361

Ответ 1

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

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

Ответ 2

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

Изменить: ok Я подробно рассмотрел вашу проблему, проблема заключается в том, что вы пытаетесь добавить фрагмент, который уже был добавлен. Даже если вы используете замену или удаление вызовов, вы не можете этого сделать. Только работа, которую я нашел, - это создать новый экземпляр фрагмента и добавить его каждый раз. После удаления или замены фрагмента лучше всего отбросить все ссылки на него, чтобы GC мог позаботиться об этом.

Ответ 3

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

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

Ответ 4

Проверьте, добавлен ли frament или нет с помощью метода fragment.isAdded(). Замените или добавьте фрагмент соответственно.

Ответ 5

попробуйте это после фрагментаTransection.replace()

fragmentTransection.addToBackStack(null);
fragmentTransection.commitAllowingStateLoss();

Ответ 6

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

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

Ответ 7

Я пробовал звонить FragmentTransaction.remove() из onTabUnselected(), и он работал над этой ошибкой.

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    ft.add(R.id.fragment_container, fragment, null);
}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    ft.remove(fragment);
}

Ответ 8

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

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

Ответ 9

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

Ответ 10

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

Ответ 11

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