Это правильный способ очистки фрагментов назад, оставив глубоко вложенный стек?

StackOverflow https://stackoverflow.com/questions/5802141

Вопрос

Я использую библиотеку совместимости Android для реализации фрагментов и расширил образец макета, так что фрагмент содержит кнопку, которая снимает другой фрагмент.

В панели выбора слева у меня есть 5 выбираемых элементов - A B C D E.

Каждый загружает фрагмент (через FragmentTransaction:replace) в панели деталей - a b c d e

Теперь я расширил фрагмент e Чтобы содержать кнопку, которая загружает другой фрагмент e1 Также на панели деталей. Я сделал это на фрагменте eS 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();
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top