В чем смысл addToBackStack с нулевым параметром?

97

У меня есть код клиента. Существует только одно действие для всех фрагментов, т.е. одно действие управляет всеми фрагментами.

Это действие содержит следующий код для любого фрагмента в конце метода этого фрагмента:

Например - фрагмент MoreFragment:

MoreFragment firstFragment = new MoreFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.article_fragment, firstFragment)
.addToBackStack(null).commit();

Так,

1) Что означает, за addToBackStack(null)которым следует а commit()?

2) Почему вам нужно передать нулевой параметр addToBackStack?

3) Как получить этот фрагмент после такого добавления?

Похоже, этот код бесполезен, поскольку я запускал код без последней строки, .addToBackStack(null).commit()и он работал без каких-либо проблем.

О Господи
источник
developer.android.com/reference/android/app/… в некоторых случаях вы должны вызвать этот метод.
Люцифер
3
Вы можете передать имя фрагмента в качестве параметра в addToBackStack (name) вместо Null. Если вы передадите Null, вы не сможете использовать метод FragmentManager.popBackStackImmediate (String name, int flags); или popBackStack (String name, int flags); потому что имя было Null. Так что методы popBackstack работать не будут. Я предлагаю вам передать имя фрагмента в качестве параметров вместо передачи null.
luckylukein

Ответы:

114

В чем смысл addToBackStack (null), за которым следует commit ()?

Цитата документов:

При вызове addToBackStack () транзакция замены сохраняется в заднем стеке, поэтому пользователь может отменить транзакцию и вернуть предыдущий фрагмент, нажав кнопку «Назад».

Если вы добавляете несколько изменений в транзакцию (например, еще один add () или remove ()) и вызываете addToBackStack (), то все изменения, примененные до того, как вы вызываете commit (), добавляются в задний стек как одна транзакция и кнопка Назад изменит их все вместе.

Порядок, в котором вы добавляете изменения в FragmentTransaction, не имеет значения, за исключением:

Вы должны позвонить commit()последним. Если вы добавляете несколько фрагментов в один и тот же контейнер, то порядок, в котором вы добавляете их, определяет порядок, в котором они отображаются в иерархии представлений.

Так что вы должны в конце концов совершить.

Почему вам нужно передать нулевой параметр в addToBackStack?

Необязательно иметь значение NULL, это может быть строка. Если не хотите, просто передайте null.

общедоступный абстрактный FragmentTransaction addToBackStack (имя строки)

Добавлено в API уровня 11. Добавьте эту транзакцию в задний стек. Это означает, что транзакция будет запомнена после того, как она будет зафиксирована, и обратит свою операцию, когда позже будет извлечена из стека.

Имя параметра Необязательное имя для этого состояния заднего стека или null.

Что касается:

Похоже, этот код бесполезен, поскольку я запускал код без последней строки .addToBackStack (null) .commit (), и он работал без каких-либо проблем

Если вы хотите перейти к предыдущему фрагменту, добавьте его в стопку. Так что это зависит от того, хотите ли вы добавить фрагмент в backstack.

Как получить этот фрагмент после такого добавления?

У вас уже есть экземпляр фрагмента firstFragment. Так что я не понимаю, что вы имеете в виду, говоря получить фрагмент позже.

Дополнительная информация @

http://developer.android.com/guide/components/fragments.html

http://developer.android.com/reference/android/app/FragmentTransaction.html#addToBackStack(java.lang.String)

Рагхунандан
источник
Вы также можете добавить это к своему ответу из документа API: Добавьте эту транзакцию в задний стек. Это означает, что транзакция будет запомнена после того, как она будет зафиксирована, и обратит свою операцию, когда позже будет извлечена из стека. Имя параметра Необязательное имя для этого состояния заднего стека или null.
Dyrborg
Итак, как я понял, вся цель добавления в backstack - выполнить навигацию, как мы делаем с кнопкой назад, чтобы перейти к предыдущему фрагменту?
Боже мой
Хорошо, если вы передаете параметр в addToBackStack, тогда зачем нам это делать, getFragmentManager().popBackStackImmediate()если кнопка возврата может делать это сама по себе с / без передачи параметра? См. Ответ - stackoverflow.com/questions/21156153/…
Боже мой
@VedPrakash вам не нужно. Кроме того, это совершенно разные вопросы и ответы. Вы можете легко узнать себя, добавив два фрагмента в заднюю стопку и нажав кнопку возврата
Рагхунандан
@VedPrakash прочитал управление фрагментами @ developer.android.com/guide/components/fragments.html
Raghunandan
17

tagСтрока в addToBackStack(String name)дает способ найти стек обратно на потом выскочить прямо на этом месте. Он предназначен для использования в методе popToBackStack(String name, int flags):

Извлечь последний переход фрагмента из обратного стека фрагментов менеджера. Эта функция является асинхронной - она ​​ставит запрос на извлечение, но действие не будет выполнено, пока приложение не вернется в свой цикл обработки событий.

name: Если не равно NULL, это имя предыдущего состояния возврата, которое нужно искать; если он найден, все состояния до этого состояния будут выскакивать. Флаг POP_BACK_STACK_INCLUSIVE может использоваться, чтобы контролировать, выталкивается ли само названное состояние. Если null, отображается только верхнее состояние.

флаги: либо 0, либо POP_BACK_STACK_INCLUSIVE.

Другими словами, он будет выталкивать ваш задний стек, пока не найдет фрагмент, который был добавлен nameв addToBackStack(String name).

Например, если вы выполняете серию добавлений или замен в диспетчере фрагментов, задавая имена "frag1", "frag2", "frag3", "frag4", а затем хотите вернуться непосредственно к фрагменту 2, добавленному с помощью addToBackStack (" frag2 "), вы звоните popToBackStack("frag2", 0).

Так,

  • Использование .addToBackStack("fragName"): если вы хотите позже popToBackStack(String name, int flags)вытащить более одной задней стопки.

  • Использование .addToBackStack(null): Если вы не хотите, чтобы позже выскакивали более одной задней стопки, но все же хотите выталкивать по одной за раз. Сделайте это, даже если вы не будете явно вызывать popToBackStack (), а вместо этого позволите реализации по умолчанию для обратной печати обрабатывать задний стек.

  • Использование .disallowAddToBackStack(): Если вы не хотите, чтобы ни обратное нажатие, ни вызов popBackStack () явно не выполнялись. Он будет следить за тем, чтобы ни одна часть кода не использовала .addToBackStack ().

Аллан Велосо
источник
1

Ваши ответы устарели. Если вы не хотите добавлять фрагменты в задний стек, вам следует использовать приведенный ниже фрагмент кода:

    public static void replaceFragment (@NonNull FragmentManager fragmentManager,
            @NonNull Fragment fragment, int frameId){

        checkNotNull(fragmentManager);
        checkNotNull(fragment);
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(frameId, fragment);
        transaction.disallowAddToBackStack(); // <-- This makes magic!
        transaction.commit();
    }

Ниже у вас есть симпатичный пример того, как его использовать:

GameFragment fragment = GameFragment.newInstance(mGameObject, currentQuestion);
ActivityUtils.replaceFragment(getFragmentManager(), fragment, R.id.main);
Элиаш Кубала
источник
6
Устарело где? Я ничего не вижу ни в документации, ни в источнике FragmentTransaction.
Руп
3
Остерегайтесь, если вы disallowAddToBackStack, то любые будущие вызовы в addToBackStack выбросит IllegalStateException. Если addToBackStack уже был вызван, этот метод вызовет исключение IllegalStateException.
Kathir