Как заменить более одного фрагмента другим в заднем стеке?

У меня есть следующие фрагменты в заднем стеке A, B, C. Затем я хочу добавить фрагмент D, но в задний стек я хочу поместить A и D вместо A, B, C, D. Проблема в том, когда я пытаюсь удалить B и C с transaction.remove(), backStackEntryCount все еще старый, который делает пустые экраны при нажатии назад. Есть ли способ справиться с этим?

Когда я использую popBackStack()он идет к фрагменту A, затем идет D, который создает странные анимационные эффекты.

РЕДАКТИРОВАТЬ: Вопрос не является дубликатом, как он был отмечен, потому что этот вопрос больше предназначен для управления порядком нескольких фрагментов в заднем стеке.

3 ответа

Решение

При добавлении в Backstack, вы можете включить имя для добавления backstack, когда вы находитесь в определенном состоянии. Основано на документации для FragmentManager # popBackStack (string, int);:

Получите последний переход фрагмента из стека назад менеджера. Если нечего выдавать, возвращается false. Эта функция является асинхронной - она ​​ставит запрос на выдвижение, но действие не будет выполнено, пока приложение не вернется в свой цикл обработки событий.

параметры

name String: Если не ноль, это имя предыдущего состояния назад, которое нужно искать; если найдено, все состояния до этого состояния будут вытолкнуты. Флаг POP_BACK_STACK_INCLUSIVE может быть использован для управления тем, не вышло ли само названное состояние в очередь. Если ноль, только верхнее состояние выталкивается.

flags int: либо 0, либо POP_BACK_STACK_INCLUSIVE.

Так что в этом случае вы:

Добавьте фрагмент A в контейнер и в корневой backstack. Дайте ему имя, чтобы вы могли ссылаться на него при появлении сообщения.

Фрагмент А:

FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentA, "FragmentA")
.addToBackStack("first")
.commit();

Добавить фрагмент B в контейнер (заменить или добавить, не имеет значения). Добавьте в backstack "null" или другое имя, если хотите. Он должен отличаться от "первого".

Фрагмент Б:

FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentB, "FragmentB")
.addToBackStack(null)
.commit();

Добавьте или замените фрагментом C, как если бы вы использовали фрагмент B.

Фрагмент С:

FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentC, "FragmentC")
.addToBackStack(null)
.commit();

Добавьте или замените фрагментом D, как если бы вы использовали фрагмент B и C.

Фрагмент D:

FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentD, "FragmentD")
.addToBackStack(null)
.commit();

Затем в onBackPressed() сначала вы проверяете, находится ли Fragment D в стеке. Если это так, то вставьте полностью обратно в корень (который в данном случае является "первым"). Если нет, просто держите спину нажатой, как обычно.

@Override
public void onBackPressed() {
    FragmentManager fm = getFragmentManager();
    if (fm.findFragmentByTag("FragmentD") != null) {
       fm.popBackStack("first", 0); // Pops everything up to "first" 
    } else {
       super.onBackPressed(); // Pops backstack like normal or leaves App if at base.
    }
}

Что это должно сделать, это позволить вашим пользователям возвращаться "назад", когда они нажимают кнопку "Назад" во фрагментах A, B или C. Затем, когда они, наконец, находятся во фрагменте D, он полностью возвращается к A.

Фрагмент А

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, FragmentA, "FragmentA");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();

Фрагмент Б

fragmentTransaction.replace(R.id.fragment_container, FragmentB, "FragmentB");

Фрагмент С

 fragmentTransaction.replace(R.id.fragment_container, FragmentC, "FragmentC");

Фрагмент D

 fragmentTransaction.replace(R.id.fragment_container, FragmentD, "FragmentD");

Теперь ваш onBackPressed() в активности

@Override
public void onBackPressed() {


int lastStack = getSupportFragmentManager().getBackStackEntryCount();
try {
    //If the last fragment was named/tagged "three"
    if (getSupportFragmentManager().getFragments().get(lastStack).getTag().toString()=="FragmentD"){

        getSupportFragmentManager().popBackStackImmediate();//skip c
        getSupportFragmentManager().popBackStackImmediate();//skip B
         Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentA");
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment_container, fragment);
        transaction.commit();
        return;
    }
} catch (Exception e) {

    e.printStackTrace();
}

super.onBackPressed();
 }

Сделайте фрагмент_контейнера для каждого фрагмента и продолжайте заменять фрагмент_контейнера новейшего фрагмента. Не забывайте:

addToBackStack(null);
Другие вопросы по тегам