На кнопке «Назад», как отобразить фрагмент, определенный в XML-макете, после того, как он был заменен другим фрагментом

#android #android-fragments

Вопрос:

У меня есть задание, макет которого включает фрагмент:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@ id/fragment_container"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical">

        <fragment
            android:id="@ id/fragment_main"
            android:name="com.MyMainFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    </RelativeLayout>
 

При нажатии кнопки основной фрагмент заменяется фрагментом B:

 public void diplayFragmentB() {

    Fragment mainFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_main);
    getSupportFragmentManager().beginTransaction()
            .hide(mainFragment) 
            .commit();

    FragmentB fragmentB = new FragmentB();
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.fragment_container, fragmentB);
    transaction.commit();
    transaction.addToBackStack(null);
}
 

Когда пользователь нажимает кнопку «Назад», вместо основного фрагмента отображается пустой экран.
Каково решение для отображения основного фрагмента ?

Я попытался переопределить onBackPressed() следующим образом:

 @Override
public void onBackPressed() {
    if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
        super.onBackPressed();

        Fragment mainFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_main);
        getSupportFragmentManager().beginTransaction()
                .show(mainFragment)
                .commit();
    } else {
        finish();
    }
}
 

Ответ №1:

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

 public void diplayFragmentB() {
    // Not really necessary fragment manager can handle it
//  Fragment mainFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_main);
//     getSupportFragmentManager().beginTransaction()
//             .hide(mainFragment) 
//             .commit();

    // In documentation, it is recommended to pass the class as a parameter instead of instance
    // FragmentB fragmentB = new FragmentB();
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction()
        .setReorderingAllowed(true)
        .replace(R.id.fragment_container, FragmentB.class, null)
        .addToBackStack(null)
        .commit();
}


@Override
public void onBackPressed() {
    FragmentManager fragmentManager = getSupportFragmentManager();
    if (fragmentManager.getBackStackEntryCount() > 0) {
        // Since you have only one level you can use directly popBackStack()
        fragmentManager.popBackStack();
    }
    super.onBackPressed();
}
 

Попробуйте этот код и дайте мне отзыв для получения дополнительной помощи.

Комментарии:

1. Пожалуйста. Я переместил назначение FragmentManager выше оператора if. Так будет лучше. Кстати, спасибо за исправление орфографии 🙂 .