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, Я все еще пытаюсь найти способ сохранить диалог, который вызывается через фрагмент.

Другие вопросы по тегам