DialogFragment исчезает после поворота устройства, несмотря на применение общих исправлений
У меня есть DialogFragment, который я запускаю, когда пользователь нажимает на элемент меню на панели действий. Все в диалоге работает правильно - он запускается просто отлично и делает все, что я для него настроил. К сожалению, как только я поворачиваю свое устройство, DialogFragment исчезает.
Это казалось обычной проблемой еще в 2012 году - я изучил Stackru и попробовал все распространенные исправления, которые были опубликованы в последние пару лет. Этот пост SO, в частности, суммирует все возможные исправления, которые были предложены:
- Настройте DialogFragment для использования парадигмы newInstance()
- добавлять
setRetainInstance(true)
к ДиалогФрагментуonCreate()
- Добавить обходной путь к
onDestroyView()
устранить потенциальную ошибку в библиотеке поддержки
Несмотря на реализацию всего вышеперечисленного, DialogFragment отказывается задерживаться после поворота устройства.
Вот как я запускаю DialogFragment из Activity:
DialogKanjiLookup dialog = DialogKanjiLookup.newInstance(gSearchView.getQuery());
dialog.show(getSupportFragmentManager(), "dialogKanjiLookup");
Вот это ДиалогФрагмент newInstance()
:
public DialogKanjiLookup() {}
public static DialogKanjiLookup newInstance(CharSequence searchTerm)
{
DialogKanjiLookup dialog = new DialogKanjiLookup();
Bundle args = new Bundle();
args.putCharSequence(BUNDLE_SEARCH, searchTerm);
dialog.setArguments(args);
return dialog;
}
Вот диалог onCreateDialog():
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
// Specify a layout for the dialog
LayoutInflater inflater = getActivity().getLayoutInflater();
View layout = inflater.inflate(R.layout.dialog_kanjilookup, null);
// SNIP
// ...Handle savedInstanceState, set up various Listeners and adapters...
// SNIP
// Create the actual dialog
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Customize the dialog
builder.setTitle(R.string.dialog_kanji_lookup_title);
builder.setIcon(R.drawable.kanji_lookup);
builder.setPositiveButton(R.string.menu_search, btnSearchListener);
builder.setNegativeButton(R.string.cancel, null);
builder.setView(layout);
// Force the dialog to take up as much space as it can
Dialog dialog = builder.create();
dialog.show();
dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
// Display the dialog
return dialog;
}
Там только один случай DialogFragment.dismiss()
вызывается из фрагмента, но это срабатывает только тогда, когда пользователь нажимает одну из кнопок диалога, поэтому я исключил это. Почему мой DialogFragment все еще исчезает после поворота? Я чуть не потянул за это волосы, они работали нормально до тех пор, пока я не применил Навигационный ящик. Может ли это быть частью проблемы?
РЕДАКТИРОВАТЬ: Ложная тревога, я обнаружил, что мой ответ не был решением! Проблема вновь возникла после того, как я закончил перемещать все свои фрагменты и действия от использования библиотек поддержки.
Я обнаружил, что эта проблема существует только в Деятельностях, в которых фрагмент контента не был объявлен статически в макете Деятельности. То есть, если у меня есть <FrameLayout>
определены в XML и использовать fragmentManager.beginTransaction().replace(R.id.content_frame, frag, tag).commit();
чтобы загрузить фрагмент, любые DialogFragment s, запущенные в этом действии, не могут перезагрузиться, когда устройство было повернуто.
Вот экранная запись, демонстрирующая проблему: https://www.youtube.com/watch?v=psK0pzMn6oc
1 ответ
После некоторых экспериментов я нашел решение. Активность, которая запускает диалог, должна расширяться android.support.v4.app.FragmentActivity
и DialogFragment должен расширяться android.support.v4.app.DialogFragment
,
Затем, getSupportFragmentManager()
должен быть вызван при запуске DialogFragment:
CustomDialog dialog = CustomDialog.newInstance();
dialog.show(getSupportFragmentManager(), "customDialog");
Это должно сохранить диалог во время вращения. Там не было необходимости использовать setRetainInstance(true)
в самом диалоге.
Имейте в виду, это работает только в тех случаях, когда FragmentActivity
вызывает DialogFragment
, Я все еще пытаюсь найти способ сохранить диалог, который вызывается через фрагмент.