it-swarm.com.ru

Фрагмент уже добавлен 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: 

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

Так:

  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);"
51
Axel M. Garcia

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

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

41
Axel M. Garcia

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

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

12
schwiz

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

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

8
Johan Paul

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

1
Jiju Induchoodan

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

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
Nartus Team

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

fragmentTransection.addToBackStack(null);
fragmentTransection.commitAllowingStateLoss();
1
Saleh Sheper

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

0
Bombey77

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

((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();
0
Muhammad Aamir Ali

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

0
Pradeep Kumar Kushwaha

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

0
kylarsturn

Я попытался вызвать 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);
}
0
ObviousChild