Два фрагмента перекрываются из-за addBackStack

В моем основном действии нажатие кнопки «Настройки» открывает AppCompatActivity с FrameLayout в качестве контейнера для фрагментов. В методе OnCreate я добавляю фрагмент, который является контейнером PreferenceScreen.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.settings);

    Toolbar toolbar = (Toolbar) findViewById(R.id.custom_toolbar);
    setSupportActionBar(toolbar);

    ActionBar ab = getSupportActionBar();
    if (ab != null) {
        ab.setDisplayHomeAsUpEnabled(true);
        ab.setTitle("Settings");
    }


    FragmentManager fragmentManager = getSupportFragmentManager();
    Fragment fragment = null;
    if (savedInstanceState == null) {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        fragment = SettingsFragment.newInstance(null);
        fragmentTransaction.add(R.id.fragment_container, fragment);

        fragmentTransaction.commit();
    }
}

При повторном нажатии другой кнопки под названием «Параметры» открывается заменяет фрагмент фрагментом параметров, добавляя текущий класс в стопку.

@Override
public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen pref) {

    FragmentManager manager = getSupportFragmentManager();

    SettingsSubscreenFragment fragment = null;
    Bundle args = new Bundle();

    switch (pref.getKey()) {
        case "pref_key_rejection_options":
            getSupportActionBar().setTitle("Rejection Options");
            fragment = SettingsSubscreenFragment.newInstance("Options");

            break;
    }

    args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, pref.getKey());

    if (fragment != null) {
        fragment.setArguments(args);
    }

    FragmentTransaction ft = manager.beginTransaction();
    ft.replace(R.id.fragment_container, fragment, pref.getKey());
    ft.addToBackStack(null);
    ft.commit();

    return true;
}

Когда я нажимаю кнопку «Вверх», я просто заменяю фрагмент «Параметры» на первый фрагмент «Настройки», который не извлекает задний стек.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            getSupportActionBar().setTitle("Settings");

            FragmentManager fragmentManager;
            FragmentTransaction ft;
            Fragment fragment = null;

            if (getSupportFragmentManager().findFragmentByTag("pref_key_options") != null) {
                fragmentManager = getSupportFragmentManager();
                ft = fragmentManager.beginTransaction();                 

                fragment = SettingsFragment.newInstance(null);


                ft.replace(R.id.fragment_container, fragment);
                ft.commit();
                fragmentManager.getFragments().clear();


                return true;
            } else {
                return super.onOptionsItemSelected(item);
            }

    }
    return super.onOptionsItemSelected(item);
}

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

@Override
public void onBackPressed() {
    int backStackCount = getSupportFragmentManager().getBackStackEntryCount();

    if (backStackCount >= 1) {
        getSupportActionBar().setTitle("Settings");
        getSupportFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}

Почти такая же ситуация, как из здесь, третье изображение вопрос, но я не могу заставить его работать с их предложениями.

Что я делаю неправильно и что я могу сделать, чтобы это сработало? Большое спасибо.


person Mr. Nacho    schedule 03.09.2017    source источник


Ответы (1)


Убедитесь, что FragmentTransaction , SettingsSubscreenFragment и SettingsFragment расширяют android.support.v4.app.Fragment . Если нет, попробуй

class YourFragments extends android.support.v4.app.Fragment 

в ваших классах фрагментов.

person Vinayak B    schedule 03.09.2017
comment
Я использую PreferenceFragmentCompat для этих фрагментов и AppCompatActivity для действия, содержащего контейнер для этих фрагментов. Для FragmentTransaction я также использую библиотеку поддержки. - person Mr. Nacho; 04.09.2017