PopBackStack() после того, как addToBackStack не работает
Мой проект содержит два фрагмента:
- FragmentA: фрагмент, загруженный по умолчанию при запуске приложения
- FragmentB: замените
fragmentA
, когда нажимается кнопка.
Это XML моего основного представления:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/main_fragment_container"
android:name="fragmentA"
android:layout_width="match_parent"
android:layout_height="match_parent">
</fragment>
</LinearLayout>
Когда я хочу заменить fragmentA
на FragmentB
, я использую этот код:
FragmentTransaction fragmentTransaction = getSupportFragmentManager()
.beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.main_fragment_container, new FragmentB());
fragmentTransaction.commit();
Этот код работает нормально. Мой FragmentA заменяется новым FragmentB
. Но когда щелчок сделан на задней кнопке, я хочу заменить FragmentB
на fragmentA
, используя popBackStackImmediate()
.
Это код, который я использую:
if (getSupportFragmentManager().getBackStackEntryCount() > 0){
boolean done = getFragmentManager().popBackStackImmediate();
fragmentTransaction.commit();
}
Функция popBackStackImmediate
всегда возвращает false, а FragmentB
- на переднем плане.
Почему FragmentA не заменяет FragmentB, когда я вызываю popBackStackImmediate
? У кого-нибудь есть идея решить мою проблему?
заблаговременно
Ответы
Ответ 1
Вы используете getSupportedFragmentManager()
для замены FragmentA
на FragmentB
. Но вы вызываете popBackStack()
на getFragmentManager()
.
Если вы добавляете фрагменты в android.support.v4.app.FragmentManager
, вам также нужно вызвать popBackStack()
на том же FragmentManager
.
Этот код должен решить проблему:
if (getSupportFragmentManager().getBackStackEntryCount() > 0){
boolean done = getSupportFragmentManager().popBackStackImmediate();
}
Ответ 2
Вы должны позвонить
fragmentTransaction.addToBackStack(null);
после выполнения всех операций, таких как add(), remove() и replace() и непосредственно перед commit(). Только тогда эта транзакция будет добавлена в стопку. Только тогда вы сможете вернуться к предыдущему состоянию фрагмента с помощью кнопки "Назад". Подробнее здесь.
Ответ 3
Проблема заключается в том, что вы смешиваете Fragment
и методы из библиотеки поддержки.
Если вы используете библиотеку поддержки, убедитесь, что:
- ваш
Activity
выходит из android.support.v4.app.FragmentActivity
- ваш
Fragment
распространяется от android.support.v4.app.Fragment
- используйте
getSupportFragmentManager()
, чтобы получить android.support.v4.app.FragmentManager
Ваш код в Activity
будет выглядеть следующим образом:
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStackImmediate();
}
Помните, что если вы хотите получить FragmentManager
из кода Fragment
, вы должны использовать getFragmentManager, как объяснено в документации (возможно, причина некоторой путаницы, если у вас мало опыта).
Если вы не используете библиотеку поддержки:
- ваш
Activity
распространяется от android.app.Activity
- ваш
Fragment
распространяется от android.app.Fragment
- используйте
getFragmentManager()
, чтобы получить android.app.FragmentManager
Ваш код будет выглядеть следующим образом:
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStackImmediate();
}
fragmentTransaction.commit();
не требуется в обоих случаях, поэтому удалите его.
Кроме того, звоните fragmentTransaction.addToBackStack(null);
непосредственно перед commit
, но после других операций.
Ответ 4
Я предлагаю использовать замену фрагмента тегом, чтобы получить тот же результат.
Добавить фрагмент B в действие с тегом
fragmentTransaction.replace(R.id.main_fragment_container, new FragmentB(),"TAG_B");
Фрагмент A → Фрагмент B [onBackPressed] → Фрагмент A
Переопределите onBackPressed() в файлах Activity, где
//проверяем фрагмент B и вы просматриваете фрагмент B
if (getSupportFragmentManager().findFragmentByTag("TAG_B")!=null)
{
fragmentTransaction.replace(R.id.main_fragment_container, new FragmentA(),"TAG_A");
}
addToBackStack ( "TAG" ) и popBackStackImmediate ( "TAG" ) всегда возвращаются к условию фрагмента без каких-либо данных в пользовательском интерфейсе непосредственно до создания или добавления фрагмента в действие!
Ответ 5
Если вы боретесь с addToBackStack() и popBackStack(), просто используйте
FragmentTransaction ft =getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, new HomeFragment(), "Home");
ft.commit();`
В вашей деятельности В OnBackPressed() найдите мерцание по тегу, а затем сделайте свой материал
Fragment home = getSupportFragmentManager().findFragmentByTag("Home");
if (home instanceof HomeFragment && home.isVisible()) {
// do you stuff
}
Для получения дополнительной информации https://github.com/DattaHujare/NavigationDrawer Я никогда не использую addToBackStack() для обработки фрагмента.