Является ли это правильным способом очистки стопы фрагмента при выходе из глубоко вложенного стека?
Я использую библиотеку совместимости Android для реализации фрагментов и расширил образец макета, чтобы фрагмент содержал кнопку, которая запускает другой фрагмент.
В области выбора слева у меня есть 5 выбираемых элементов - A B C D E
.
Каждый загружает фрагмент (через FragmentTransaction:replace
) в панели сведений - A B C D E
Теперь я расширил фрагмент e
, чтобы содержать кнопку, которая загружает еще один фрагмент e1
также в области сведений. Я сделал это по методу фрагмента e
onClick следующим образом:
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
все еще находится в стеке. Кроме того, после щелчка мыши я получил исключение нулевого указателя в onCreateView:
Чтобы решить эту проблему, я добавил следующее при каждом выборе A B C D E
:
FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
Просто интересно, правильно ли это решение или я должен делать что-то другое?
Ответы
Ответ 1
Ну, есть несколько способов сделать это в зависимости от предполагаемого поведения, но эта ссылка должна дать вам все лучшие решения и не удивительно, что это Dianne Hackborn
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
),
Ответ 2
Другое чистое решение, если вы не хотите всплывать все записи стека...
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().beginTransaction().replace(R.id.home_activity_container, fragmentInstance).addToBackStack(null).commit();
Сначала очистка стека, а затем загрузка нового фрагмента, поэтому в любой заданной точке вы будете иметь только один фрагмент в стеке
Ответ 3
Благодаря ответу Joachim, я использую код, чтобы окончательно очистить все записи в обратном стеке.
// 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 */
Ответ 4
Я много исследовал для очистки Backstack и наконец увидел Transaction BackStack и его управление. Вот решение, которое наилучшим образом помогло мне.
// CLEAR BACK STACK.
private void clearBackStack() {
final FragmentManager fragmentManager = getSupportFragmentManager();
while (fragmentManager.getBackStackEntryCount() != 0) {
fragmentManager.popBackStackImmediate();
}
}
Вышеупомянутый метод перебирает все транзакции в backstack и сразу же удаляет их по одному.
Примечание: выше код некогда не работает, и я сталкиваюсь с ANR из-за этого кода, поэтому, пожалуйста, не пробуйте это.
Обновление
ниже метод удаляет все сегменты этого "имени" из backstack.
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack("name",FragmentManager.POP_BACK_STACK_INCLUSIVE);
- name Если не null, это имя предыдущего обратного состояния
искать; если найдено, все состояния до этого состояния будут выскочены.
- Флаг POP_BACK_STACK_INCLUSIVE может использоваться для управления выводом самого имени. Если значение null, то выводится только верхнее состояние.
Ответ 5
Я использую такой же код, как те, которые используют цикл while, но я вызываю счетчик записей в каждом цикле... поэтому я предполагаю, что он несколько медленнее
FragmentManager manager = getFragmentManager();
while (manager.getBackStackEntryCount() > 0){
manager.popBackStackImmediate();
}
Ответ 6
// pop back stack all the way
final FragmentManager fm = getSherlockActivity().getSupportFragmentManager();
int entryCount = fm.getBackStackEntryCount();
while (entryCount-- > 0) {
fm.popBackStack();
}