Показывать диалог над пейджером с вложенными фрагментами
Я настроил очень простой тестовый проектhttps://github.com/ArtworkAD/ViewPagerDialogTest Чтобы оценить следующую ситуацию: основное действие имеет пейджер представления, в котором размещается отдельный фрагмент с помощью менеджера фрагментов поддержки:
public class MainActivity extends AppCompatActivity {
// ...
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
// ...
tabLayout.setupWithViewPager(viewPager);
}
@Override
protected void onResume() {
super.onResume();
MainActivity.CustomDialog dialog = (MainActivity.CustomDialog) getSupportFragmentManager().findFragmentByTag(MainActivity.CustomDialog.TAG);
if (dialog == null) {
new MainActivity.CustomDialog().show(getSupportFragmentManager().beginTransaction(), MainActivity.CustomDialog.TAG);
}
}
// ...
}
Когда действие возобновляется, фрагмент диалога отображается внутри основного действия.
Единственный фрагмент в пейджере представления определяется следующим образом:
public class RootFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.root_fragment, container, false);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction().add(R.id.root_frame, new FirstLevelFragment(), "ROOT").commit();
}
return root;
}
}
Этот корневой фрагмент позволяет нам складывать другие фрагменты в «root_frame». Таким образом, мы складываем другое и другое:
public class FirstLevelFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setRetainInstance(true);
View root = inflater.inflate(R.layout.first_level_fragment, container, false);
root.findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SecondLevelFragment f = (SecondLevelFragment) getActivity().getSupportFragmentManager().findFragmentByTag("NESTED");
if (f == null) {
getActivity().getSupportFragmentManager().beginTransaction().add(R.id.root_frame, new SecondLevelFragment(), "NESTED").addToBackStack(null).commit();
}
}
});
return root;
}
public static class SecondLevelFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setRetainInstance(true);
return inflater.inflate(R.layout.second_level_fragment, container, false);
}
}
}
Это прекрасно работает! Идея укладки взята изhttps://stackoverflow.com/a/21453571/401025 , Однако, когда отображается диалоговое окно, и пользователи переходят к фрагменту второго уровня и поворачивают экран, я получаю следующее исключение:
E / AndroidRuntime: java.lang.RuntimeException: Невозможно запустить действие ComponentInfo {de.azzoft.viewpagerdialogtest / de.azzoft.viewpagerdialogtest.MainActivity}: java.lang.IllegalArgumentException: не найдено представление для идентификатора 0x7f0c0083 (de.azzog.test id / root_frame) для фрагмента SecondLevelFragment {15c0db38 # 0 id = 0x7f0c0083 NESTED}
E / AndroidRuntime: Причина: java.lang.IllegalArgumentException: не найдено представление для идентификатора 0x7f0c0083 (de.azzoft.viewpagerdialogtest: id / root_frame) для фрагмента SecondLevelFragment {15c0db38 # 0 id = 0x7f0c0083 NESTED}
Полная трассировка стека:https://github.com/ArtworkAD/ViewPagerDialogTest/blob/master/README.md
Без появления диалога все работает отлично. Вы можете проверить это, загрузив тестовый проект.
Кажется, что диалог, который на самом деле является фрагментом, портит иерархию фрагментов, когда он добавляется в действие. Любые идеи, как это исправить?
Важно, чтобы второй фрагмент был сохранен.