Как удалить определенный фрагмент из предыдущего стека в android

У меня проблема с удалением определенного фрагмента из предыдущего стека. Мой сценарий похож на этот. Фрагмент-1 заменяется фрагментом-2, а затем фрагмент-2 заменяется фрагментом-3.

Заказ вызова; Фрагмент-1 → Фрагмент-2 -. > Фрагмент-3

Когда Fragment-3 находится на экране, а затем нажмите кнопку "Назад", я хочу пойти

Фрагмент-1.Это означает, что я хочу удалить фрагмент-2 из предыдущего стека.

Как это сделать?

Ответ 1

В backstack у вас нет Fragment s, но FragmentTransaction s. Когда вы popBackStack() транзакция применяется снова, но назад. Это означает, что (при условии, что вы addToBackStackTrace(null) каждый раз) у вас есть

1->2
2->3

Если вы не добавите вторую транзакцию в backstack, результат будет таким, что ваш backstack - это просто

1->2

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

//from fragment-2:
getFragmentManager().popBackStack();
getFragmentManager().beginTransaction()
   .replace(R.id.container, fragment3)
   .addToBackStack(null)
   .commit();

Что я здесь делаю: из фрагмента 2 я возвращаюсь к фрагменту 1, а затем прямо к фрагменту 3. Таким образом, кнопка возврата снова вернет меня с 3 на 1.

Ответ 2

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

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

if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
        getSupportFragmentManager().popBackStackImmediate();
}
...
fragmentTransaction.replace(R.id.main_fragment, newFrag, MAIN_FRAGMENT_TAG);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.commit();

Это успешно:

  • A → B (назад нажата) → назад к A

  • A → B → C (назад нажата) → назад к A

Единственным недостатком, который я вижу, является то, что есть быстрая вспышка, где фрагмент A отображается до перехода к фрагменту C.

Ответ 3

Если вы добавляете/запускаете все три фрагмента в одной и той же активности, вместо метода add() FragmentTransaction для показа Fragment3, используйте метод replace() для FragmentTransaction (замените Fragment2 на Fragment3). Метод replace удаляет текущий фрагмент из backstack перед добавлением нового фрагмента. Если вы запускаете Fragment3 из другой активности и, следовательно, вы не можете/не хотите использовать replace(), удалите Fragment2 из backstack перед запуском нового действия (которое добавляет фрагмент3):

// in Fragment2, before adding Fragment3:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
               .remove(this) // "this" refers to current instance of Fragment2
               .commit();
fragmentManager.popBackStack();
// now go ahead and launch (add) fragment3
// if fragment3 is launched from a different activity, 
// start that activity instead
fragmentManager.beginTransaction()
               .add(R.id.a_container_view_in_activity, new Fragment3(),
                    Fargment3.FRAGMENT3_ID)
               .commit();

Ответ 4

Вы добавляете в состояние возврата из FragmentTransaction и удаляете из Backstack с помощью методов FragmentManager pop:

FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove(myFrag);
trans.commit();
manager.popBackStack();

ИЛИ

Просто вы можете пропустить фрагмент из добавления в стек фрагмента, поэтому, когда вы вернетесь с Fragment-3, он вернется к Fragment-1

Обновлено:

Чтобы отключить анимацию, вам необходимо переопределить метод onCreateAnimation...

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    if (disableAnim) {
        Animation a = new Animation() {};
        a.setDuration(0);
        return a;
    }
    return super.onCreateAnimation(transit, enter, nextAnim);
}

Ответ 5

Код для Фрагмент A Фрагмент B:

Добавить Фрагмент A в BackStack фрагментов

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout_container, new fragmentB());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();

Код для Фрагмент B Фрагмент C:

Не добавлять Фрагмент B в BackStack фрагментов

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout_container, new fragmentC());
fragmentTransaction.commit();

Он будет работать следующим образом: A → B → C, а возвращает C- > A, как вы это сделали.

Надеюсь, это поможет вам.

Ответ 6

   for (int i = 0; i < mFragmentManager.getBackStackEntryCount(); i++) {
        currentFragment = mFragmentManager.getFragments().get(i);
        if (!(currentFragment instanceof ParticularFragment))
            mFragmentManager.popBackStack();
        else
            break;
    }