Как заменить более одного фрагмента другим в заднем стеке?
У меня есть следующие фрагменты в заднем стеке 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);