Android FragmentTransaction.addToBackStack путаница
Я изучал фрагменты и немного путался при дифференцировании вызовов FragmentTransaction.replace(id, fragment, tag)
и FragmentTransaction.addToBackStack(tag)
. Допустим, что мой текущий фрагмент FragmentA, а затем я загрузил FragmentB. Я хочу, чтобы в будущем, когда мне нужно загрузить FragmentA, мне не нужно его перезагружать. Просто загрузите старый в старом состоянии. Я использовал следующий сегмент кода:
public void loadFragment(Fragment fragmentB, String tag) {
FragmentManager fm = getSupportFragmentManager();
View fragmentContainer = findViewById(R.id.fragment_container);
FragmentTransaction ft = fm.beginTransaction();
ft.replace(fragmentContainer.getId(), fragmentB, tag);
ft.addToBackStack(tag);
ft.commit();
}
Теперь я смущен, где я должен добавить тег строки? В replace()
или в addToBackStack()
или в обоих вызовах? Можете ли вы объяснить разницу между этими двумя тегами?
Ответы
Ответ 1
Можете ли вы объяснить разницу между этими двумя тегами?
Документация для addToBackStack
довольно понятна:
Необязательное имя для этого состояния заднего стека, или null.
Пока для replace
:
Необязательное имя тега для фрагмента, для последующего извлечения фрагмента с FragmentManager.findFragmentByTag(String).
Итак, эти два параметра независимы, один идентифицирует задний стек, а другой идентифицирует фрагмент внутри Activity FragmentManager
.
Ваш код кажется правильным с этой точки зрения, просто чтобы я не искал представление fragmentContainer
по его идентификатору, только чтобы использовать его идентификатор для замены фрагмента. Сделайте это проще:
public void loadFragment(Fragment fragmentB, String tag) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment_container, fragmentB, tag);
ft.addToBackStack(null);
ft.commit();
}
Если вам не нужно позже идентифицировать этот задний стек, пропустите null для addToBackStack
. По крайней мере, я всегда это делаю.
Ответ 2
В этом примере вам не нужно добавлять теги в качестве идентификатора.
Просто выполните:
ft.replace(R.id.fragment_container,fragmentB);
ft.addToBackStack(null);
ft.commit();
Тег как идентификация обычно используется, когда вы хотите добавить фрагмент без пользовательского интерфейса.
Ответ 3
Параметр, переданный в addToBackStack()
, может использоваться для извлечения всего объекта BackStackEntry, а не только одного фрагмента. Чтобы установить тег фрагмента, рассмотрите возможность использования 3-param-версий add (int, Fragment, String) и replace (int, Fragment, String)
До добавления фрагмента вы сможете проверить, находится ли этот фрагмент уже в стеке, используя:
getFragmentMangager().findFragmentByTag(SettingsFragment.TAG);
Это вернет null
, если Fragment
еще не добавлен.
Ответ 4
Передача null в addtoBackStack (null) означает добавление фрагмента в стек фрагментов, но не добавление тега, который можно было бы использовать для идентификации конкретного фрагмента в стеке перед повторным добавлением.
.addToBackStack(null);
Но передача TAG в addToBackStack помогает идентифицировать фрагмент в стеке фрагментов с помощью TAG. подобно
.addToBackStack(FragmentName.TAG);
Теперь мы можем проверить фрагмент перед добавлением его в стек:
getFragmentManager().findFragmentByTag(SettingsFragment.TAG);
Это возвратит нуль, если Фрагмент еще не добавлен.