Вложенные фрагменты и задний стоп
Поддерживает ли Back Stack взаимодействие с вложенными фрагментами в Android?
Если это так, что я делаю неправильно? В моей реализации кнопка "Назад" полностью игнорирует тот факт, что я добавил эту транзакцию в задний стек. Я надеюсь, что это не из-за проблемы с вложенными фрагментами, а просто с неправильным выполнением.
Следующий код находится внутри одного из моих фрагментов и используется для замены нового фрагмента с любым вложенным фрагментом в настоящее время:
MyFragment fragment = new MyFragment();
FragmentTransaction ft = getChildFragmentManager().beginTransaction();
ft.setCustomAnimations(R.animator.slide_in_from_right, R.animator.slide_out_left, R.animator.slide_in_from_left, R.animator.slide_out_right);
ft.addToBackStack(null);
ft.replace(R.id.myFragmentHolder, fragment);
ft.commit();
Ответы
Ответ 1
У меня та же проблема, я хотел бы вставить фрагменты и сохранить задний стек для каждого вложенного фрагмента.
Но... похоже, что этот случай не обрабатывается библиотекой поддержки v4. В коде FragmentActivity в библиотеке я могу найти:
public void onBackPressed() {
if (!mFragments.popBackStackImmediate()) {
finish();
}
}
mFragments представляет FragmentManager активности, но не кажется, что этот менеджер "распространяет" поп для менеджеров детей.
Обходным путем было бы вручную вызвать popBackStackImmediate() в дочернем менеджере, как это происходит в деятельности, унаследованной от FragmentActivity:
private Fragment myFragmentContainer;
@Override
public void onBackPressed() {
if (!myFragmentContainer.getChildFragmentManager().popBackStackImmediate()) {
finish(); //or call the popBackStack on the container if necessary
}
}
Там может быть лучший способ и более автоматизированный способ, но для моих нужд это все в порядке.
Ответ 2
В моем текущем проекте у нас есть несколько "вложенных слоев", поэтому я придумал следующее обходное решение, чтобы автоматически поместить backstack только для менеджеров фрагментов верхнего уровня:
@Override
public void onBackPressed() {
SparseArray<FragmentManager> managers = new SparseArray<>();
traverseManagers(getSupportFragmentManager(), managers, 0);
if (managers.size() > 0) {
managers.valueAt(managers.size() - 1).popBackStackImmediate();
} else {
super.onBackPressed();
}
}
private void traverseManagers(FragmentManager manager, SparseArray<FragmentManager> managers, int intent) {
if (manager.getBackStackEntryCount() > 0) {
managers.put(intent, manager);
}
if (manager.getFragments() == null) {
return;
}
for (Fragment fragment : manager.getFragments()) {
if (fragment != null) traverseManagers(fragment.getChildFragmentManager(), managers, intent + 1);
}
}
Ответ 3
@Override
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
return;
}
finish();
}