Подтвердить что ты не робот

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() или в обоих вызовах? Можете ли вы объяснить разницу между этими двумя тегами?

4b9b3361

Ответ 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);

Это возвратит нуль, если Фрагмент еще не добавлен.