Очистить задний стек с помощью фрагментов



я портировал свое приложение для Android на honeycomb, и я сделал большой рефакторинг, чтобы использовать фрагменты. В моей предыдущей версии, когда я нажал кнопку Home я использовал, чтобы сделать ACTIVITY_CLEAR_TOP для того, чтобы сбросить резервную стопку.



Теперь мое приложение-это всего лишь одно действие с несколькими фрагментами, поэтому, когда я нажимаю кнопку Home, я просто заменяю один из фрагментов внутри него. Как я могу очистить свой задний стек без использования startActivity С ACTIVITY_CLEAR_TOP флаг?

770   12  

12 ответов:

Я написал что-то подобное здесь

из ответа Иоахима, от Диана Hackborn:

http://groups.google.com/group/android-developers/browse_thread/thread/d2a5c203dad6ec42

Я закончил тем, что просто использовал:

FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {    
    fm.popBackStack();
}

но мог бы также использовать что-то вроде:

FragmentManager.popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)

который выведет все состояния до названного. Затем вы можете просто заменить фрагмент на то, что вы хотите

чтобы сделать ответ на комментарий @Warpzit и сделать его легче для других, чтобы найти.

использование:

fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

при всем уважении ко всем вовлеченным сторонам; я очень удивлен, увидев, как многие из вас могут очистить весь фрагмент обратно стека с помощью простого

fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

По данным документация для Android (относительно name аргумент - "null" в заявленных рабочих предложениях).

Если null, только верхнее состояние выскочил

Теперь, я понимаю, что мне не хватает знаний о ваших конкретных реализации (например, сколько записей у вас есть в заднем стеке в данный момент времени), но я бы поставил все свои деньги на принятый ответ, ожидая четко определенного поведения на более широком диапазоне устройств и поставщиков:

(для справки, что-то вместе с этим)

FragmentManager fm = getFragmentManager(); // or 'getSupportFragmentManager();'
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {    
    fm.popBackStack();
}

принятого ответа мне было недостаточно. Я должен был использовать:

FragmentManager fm = getSupportFragmentManager();
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {
    fm.popBackStackImmediate();
}

работает для меня и простой способ без использования цикла:

 FragmentManager fragmentManager = getSupportFragmentManager();
 //this will clear the back stack and displays no animation on the screen
 fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

очистить backstack без петель

String name = getSupportFragmentManager().getBackStackEntryAt(0).getName();
getSupportFragmentManager().popBackStack(name, FragmentManager.POP_BACK_STACK_INCLUSIVE);

здесь имя является параметром addToBackStack ()

getSupportFragmentManager().beginTransaction().
                .replace(R.id.container, fragments.get(titleCode))
                .addToBackStack(name)

Я просто хотел добавить :--

выскакивая из backstack, используя следующие

fragmentManager.popBackStack ()

Это просто удаление фрагментов из транзакции, ни в коем случае он не собирается удалять фрагмент с экрана. Так что в идеале он может быть не виден вам, но может быть два или три фрагмента сложены друг на друга,а при нажатии клавиши "Назад" пользовательский интерфейс может выглядеть загроможденным, сложенным.

просто простой пример:-

Предположим, у вас есть fragmentA, который загружает фрагмента B, используя fragmentmanager.заменить() и затем мы делаем addToBackStack, чтобы сохранить эту транзакцию. Таким образом, поток:--

Шаг 1 - > FragmentA - >FragmentB (мы перешли к FragmentB, но фрагмент A находится в фоновом режиме, не видно).

теперь вы выполняете некоторую работу в fragmentB и нажимаете кнопку Save-которая после сохранения должна вернуться к fragmentA.

Шаг 2 - > на сохранение Фрагментб, мы возвращаемся к фрагменту.

Шаг 3 - > Так что распространенная ошибка будет... во фрагменте B мы сделаем диспетчер фрагментов.заменить () fragmentB на fragmentA.

но что на самом деле происходит, мы снова загружаем фрагмент A, заменяя Фрагментb . Итак, теперь есть два фрагмента (один из Шага-1, и один из этого шага-3).

два экземпляра FragmentsA сложены друг на друга, которые могут быть не видны , но они есть.

Так что даже если мы очистим backstack вышеуказанными методами, транзакция будет очищена, но не фактические фрагменты. Так что в идеале в таком конкретном случае, при нажатии кнопки save вам просто нужно вернуться к fragmentA, просто сделав fm.popBackStack () или fm.popBackImmediate ().

поэтому правильный шаг 3 - > fm.popBackStack () вернитесь к фрагменту, который уже находится в памяти.

чтение документация и изучая, что такое идентификатор фрагмента, он кажется просто индексом стека, поэтому это работает:

fragmentManager.popBackStackImmediate(0, FragmentManager.POP_BACK_STACK_INCLUSIVE);

ноль (0) - это нижняя часть стека, поэтому выскакивание до нее включительно очищает стек.

предостережение: хотя вышеизложенное работает в моей программе, я немного сомневаюсь, потому что документация FragmentManager никогда не утверждает, что идентификатор является индексом стека. Это имеет смысл, что это будет, и все мои отладки бревна обнажают, что это такое, но, возможно, в каких-то особых обстоятельствах этого не будет? Может ли кто-нибудь подтвердить это так или иначе? Если это так, то это лучшее решение. Если нет, то это вариант:

while(fragmentManager.getBackStackEntryCount() > 0) { fragmentManager.popBackStackImmediate(); }

просто используйте этот метод и передайте тег Context & Fragment, до которого нам нужно удалить фрагменты backstake.

использование

clearFragmentByTag(context, FragmentName.class.getName());



public static void clearFragmentByTag(Context context, String tag) {
    try {
        FragmentManager fm = ((AppCompatActivity) context).getSupportFragmentManager();

        for (int i = fm.getBackStackEntryCount() - 1; i >= 0; i--) {
            String backEntry = fm.getBackStackEntryAt(i).getName();
            if (backEntry.equals(tag)) {
                break;
            } else {
                 fm.popBackStack();
            }
        }
    } catch (Exception e) {
        System.out.print("!====Popbackstack error : " + e);
        e.printStackTrace();
    }
}

У меня это работает таким образом:

public void showHome() {
    getHandler().post(new Runnable() {
        @Override
        public void run() {
            final FragmentManager fm = getSupportFragmentManager();
            while (fm.getBackStackEntryCount() > 0) {
                fm.popBackStackImmediate();
            }
        }
    });
}
    private void clearBackStack(){
        SupportFragmentManaer fm = getSupportFragmentManager();
        fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

вызов этого метода будет очень аккуратно.

  1. петля не требуется.
  2. если вы используете анимацию во фрагментах, она не будет показывать слишком много анимации. Но с помощью цикла будет.
private boolean removeFragFromBackStack() {
    try {
        FragmentManager manager = getSupportFragmentManager();
        List<Fragment> fragsList = manager.getFragments();
        if (fragsList.size() == 0) {
            return true;
        }
        manager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

Comments

    Ничего не найдено.