Это правильный способ очистки фрагментов назад, оставив глубоко вложенный стек?
-
22-10-2019 - |
Вопрос
Я использую библиотеку совместимости Android для реализации фрагментов и расширил образец макета, так что фрагмент содержит кнопку, которая снимает другой фрагмент.
В панели выбора слева у меня есть 5 выбираемых элементов - A B C D E
.
Каждый загружает фрагмент (через FragmentTransaction:replace
) в панели деталей - a b c d e
Теперь я расширил фрагмент e
Чтобы содержать кнопку, которая загружает другой фрагмент e1
Также на панели деталей. Я сделал это на фрагменте e
S OnClick Method следующим образом:
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.details_frag, newFrag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
Если я сделаю следующий выбор:
E - e - e1 - D - E
Затем фрагмент e
находится в панели деталей. Это нормально и чего я хочу. Однако, если я нажму back
Кнопка на этом этапе он ничего не делает. Я должен щелкнуть по нему дважды, потому что e1
все еще в стеке. Кроме того, нажав вокруг, я получил исключение NULL Pointer в OncreateView:
Чтобы «решить» эту проблему, я добавил следующее, когда A B C D E
выбрано:
FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
Просто интересно, является ли это правильным решением или должен ли я делать что -то другое?
Решение
Ну, есть несколько способов сделать это в зависимости от предполагаемого поведения, но эта ссылка должна дать вам все лучшие решения, и неудивительно от Дайан Хакборн
http://groups.google.com/group/android-developers/browse_thread/thread/d2a5c203dad6ec42
По сути, у вас есть следующие варианты
- Используйте имя для вашего начального состояния обратного стека и используйте
FragmentManager.popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)
. - Использовать
FragmentManager.getBackStackEntryCount()
/getBackStackEntryAt().getId()
Чтобы получить идентификатор первой записи в задней стеке, иFragmentManager.popBackStack(int id, FragmentManager.POP_BACK_STACK_INCLUSIVE)
. FragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
Предполагается, что всплывает весь задний стек ... Я думаю, что документация для этого просто неправильно. (На самом деле, я думаю, это просто не покрывает случай, когда вы проходитеPOP_BACK_STACK_INCLUSIVE
),
Другие советы
Другое чистое решение, если вы не хотите выставлять все записи стека ...
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.home_activity_container, fragmentInstance).addToBackStack(null).commit();
Сначала это очистит стек, а затем загрузит новый фрагмент, поэтому в любой заданной точке у вас будет только один фрагмент в стеке
Благодаря Иоахим Ответ, я использую код, чтобы наконец очистить все записи обратного стека.
// In your FragmentActivity use getSupprotFragmentManager() to get the FragmentManager.
// Clear all back stack.
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
for (int i = 0; i < backStackCount; i++) {
// Get the back stack fragment id.
int backStackId = getSupportFragmentManager().getBackStackEntryAt(i).getId();
fm.popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} /* end of for */
Я много исследовал для очистки обратной стойки и, наконец, вижу Обратный удар транзакции и его управление. Анкет Вот решение, которое работало лучше всего для меня.
// CLEAR BACK STACK.
private void clearBackStack() {
final FragmentManager fragmentManager = getSupportFragmentManager();
while (fragmentManager.getBackStackEntryCount() != 0) {
fragmentManager.popBackStackImmediate();
}
}
Приведенный выше метод переходит к всем транзакциям в обратном стоке и сразу же удаляет их по одному.
Примечание: Выше код иногда не работает, и я сталкиваюсь Анр Из -за этого кода, поэтому, пожалуйста, не попробуйте это.
ОбновлятьНиже метод удалите все вырезок этого «имени» из обратной стороны.
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack("name",FragmentManager.POP_BACK_STACK_INCLUSIVE);
- Имя, если не ноль, это имя предыдущего состояния задних случаев, чтобы искать; Если найдено, все штаты до этого штата будут выскочены. А
- Флаг POP_BACK_STACK_INCLUCE можно использовать для контроля, выскочил ли само именованное состояние. Если NULL, то только верхнее состояние выскочило.
Я использую аналогичный код, что и те, которые используют цикл while, но я называю количество записей в каждом цикле ... поэтому я полагаю, что это несколько медленнее
FragmentManager manager = getFragmentManager();
while (manager.getBackStackEntryCount() > 0){
manager.popBackStackImmediate();
}
// pop back stack all the way
final FragmentManager fm = getSherlockActivity().getSupportFragmentManager();
int entryCount = fm.getBackStackEntryCount();
while (entryCount-- > 0) {
fm.popBackStack();
}