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

Я портировал приложение для Android на сотовые устройства, и я использовал большой рефакторинг для использования фрагментов. В моей предыдущей версии, когда я нажал кнопку "Домой", я использовал ACTIVITY_CLEAR_TOP для reset заднего стека.

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

Ответ 1

Я выложил нечто подобное здесь

От Иоахима ответ, от Дайан Хакборн:

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();
}

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

((AppCompatActivity)getContext()).getSupportFragmentManager().popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)

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

Ответ 2

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

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

fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

Ответ 3

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

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();
}

Ответ 4

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

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

Ответ 5

Работает для меня и легко, без использования цикла:

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

Ответ 6

Очистить 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)

Ответ 7

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

Выйдите из backstack, используя следующий

fragmentManager.popBackStack()

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

Просто возьмем простой пример: -

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

ШАГ 1 → FragmentA- > FragmentB (мы переместились в FragmentB, но Fragment A находится в фоновом режиме, не видно).

Теперь вы выполните некоторую работу в фрагменте B и нажмите кнопку "Сохранить", которая после сохранения должна вернуться к фрагменту.

ШАГ 2- > С сохранением FragmentB вернемся к FragmentA.

ШАГ 3 → Такая распространенная ошибка будет... в фрагменте B, мы сделаем фрагмент Manager.replace() фрагментB с фрагментом.

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

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

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

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

Ответ 8

Считывая документацию и изучая, что такое идентификатор фрагмента, он просто является индексом стека, поэтому это работает:

fragmentManager.popBackStackImmediate(0, FragmentManager.POP_BACK_STACK_INCLUSIVE);

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

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

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

Ответ 9

Просто используйте этот метод и передайте тег "Контекст" и "Фрагмент", до которого нам нужно удалить фрагменты 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();
    }
}

Ответ 10

Я работал так:

public void showHome() {
    getHandler().post(new Runnable() {
        @Override
        public void run() {
            final FragmentManager fm = getSupportFragmentManager();
            while (fm.getBackStackEntryCount() > 0) {
                fm.popBackStackImmediate();
            }
        }
    });
}

Ответ 11

Это работает для меня, попробуйте это:

public void clearFragmentBackStack() {
        FragmentManager fm = getSupportFragmentManager();
        for (int i = 0; i < fm.getBackStackEntryCount() - 1; i++) {
            fm.popBackStack();
        }
    }

Ответ 12

    private void clearBackStack(){
        SupportFragmentManaer fm = getSupportFragmentManager();
        fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

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

  1. Петля не требуется.
  2. Если вы используете анимацию во фрагментах, она не будет отображать слишком много анимаций. Но с помощью цикла будет.

Ответ 13

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;
}

Ответ 14

Привет ~ Я нашел решение, которое гораздо лучше, с: https://gist.github.com/ikew0ng/8297033

    /**
 * Remove all entries from the backStack of this fragmentManager.
 *
 * @param fragmentManager the fragmentManager to clear.
 */
private void clearBackStack(FragmentManager fragmentManager) {
    if (fragmentManager.getBackStackEntryCount() > 0) {
        FragmentManager.BackStackEntry entry = fragmentManager.getBackStackEntryAt(0);
        fragmentManager.popBackStack(entry.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }
}