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

FragmentStatePagerAdapter IllegalStateException: <MyFragment> в данный момент отсутствует в FragmentManager

Я получаю это в некоторых случаях в onResume() действия, которое использует FragmentStatePagerAdapter. При использовании устройства кнопка возврата. Не всегда. Не воспроизводится.

Я использую пакет поддержки v4, последняя редакция (8).

Уже искал с гуглом, безуспешно нашел полезный ответ.

Глядя в источник, он выкинул сюда: FragmentManager.java

@Override
public void putFragment(Bundle bundle, String key, Fragment fragment) {
    if (fragment.mIndex < 0) {
        throw new IllegalStateException("Fragment " + fragment
                + " is not currently in the FragmentManager");
    }
    bundle.putInt(key, fragment.mIndex);
}

Но почему индекс фрагмента <0 там?

Код создания экземпляров фрагментов:

@Override
public Fragment getItem(int position) {
    Fragment fragment = null;

    switch(position) {
        case 0:
            fragment = MyFragment.newInstance(param1);
            break;
        case 1:
            fragment = MyFragment2.newInstance(param2, param3);
            break;
    }
    return fragment;
}

@Override
public int getCount() {
    return 2;
}
4b9b3361

Ответ 1

Понял, причина в том, что я каждый раз вдумываю Адаптер в onResume().

Если я создаю экземпляр адаптера только один раз, в жизненном цикле активности, этого больше не происходит.

Ответ 2

Если ваш ViewPager размещен внутри фрагмента (а не активности):

mViewPager.setAdapter(новый MyFragmentStatePagerAdapter (get Ребенок FragmentManager()));

Ответ 3

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

В моем случае я переопределил getItemPosition в своем FragmentStatePagerAdapter. Моя идея должна была вернуть позицию, если элемент существует, или POSITION_NONE, если он больше не существует.

Ну, моя проблема заключалась в том, что когда моя коллекция стала пустой, я вернулся POSITION_NONE. И это сломало все.

Мое исправление заключалось в том, чтобы вернуть POSITION_UNCHANGED, когда у меня была пустая коллекция.

Надеюсь, что это поможет кому-то другому.

Ответ 4

Двумя ключевыми моментами для понимания ошибки являются:

  • Это случается иногда.
  • Это происходит в onResume().

Учитывая эту информацию, вероятно, что ViewPager не сохраняет состояние ваших Fragment s. Если вы управляете Fragment непосредственно из Activity, может случиться, что внестраничный Fragment будет уничтожен, а ваш Activity пытается манипулировать фрагментом null. Чтобы сохранить состояние Fragment, даже если оно не находится на текущем экране, исправление довольно просто:

private static final int NUM_ITEMS = 2;

ViewPager mPager = /** instantiate viewpager **/;
mPager.setOffscreenPageLimit(NUM_ITEMS-1);

Вы можете прочитать об этом здесь:

Фрагменты ViewPager со временем уничтожаются?

Ответ 5

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

Есть два способа исправить это:

1) Это происходит, когда вы вызываете onSaveInstanceState своей активности и отправляете сообщение, которое вы пытаетесь прикрепить к фрагменту, так как андроид не сможет сохранить состояние вашего фрагмента сейчас, он выдает исключение. Чтобы преодолеть это, и если вы не сохраняете состояние своего фрагмента, попробуйте использовать

commitAllowingStateLoss(), совершая транзакцию.

2) Чтобы быть очень безопасным, проверьте, правильно ли вы работаете или нет, перед прикреплением фрагмента используйте следующий код в onPause:

    boolean isInCorrectState;

    public void onCreate{
    super.onCreate();
    isInCorrectState = true;
    }

    public void onPause() {
    super.onPause();
      if(isFinishing()){
        isInCorrectState = false;
       }
    }

Теперь используйте этот флаг, чтобы проверить, находится ли ваша активность в правильном состоянии или нет, перед прикреплением фрагмента. Значение присоединяет фрагмент iff isInCorrectState == true.

Ответ 6

Для меня причина была чем-то еще.

В моем Loader.onLoaderReset() я очистил данные от адаптера. Когда я покидал приложение, onDestroy() вызвал загрузчик reset, который очистил FragmentStatePagerAdapter. Я думаю, это заставило адаптер очистить все ссылки на него. Фрагменты, но почему-то FragmentManager не заметил и выбросил Exception. Мне кажется не очень логичным.

Обратите внимание, что для меня это случилось Activity.onDestroy().

Надеюсь, что это поможет кому-то.

Ответ 7

Фрагменты в ViewPager исправлены, вместо того, чтобы пытаться заменить фрагменты в адаптере, попытайтесь дать другой набор фрагментов и notifyDataSet измениться или воспользоваться преимуществом FrameLayout, чтобы показать другой фрагмент над вкладкой пейджера представления текущего фрагмента.

Есть мое решение, которое работает:

Пролистайте жестом, применяемый на уровне фрагмента вместе с ViewPager с отключенным салфеткой по умолчанию