Подтвердить что ты не робот

Android DialogFragment исчезает после изменения ориентации

У меня есть класс v4 класса FragmentActivity, который реализует фрагменты двух сторон (вроде gmail) и кнопку, которая может вызвать диалог DialogFragment.

Все это отлично работает, если у меня нет изменений ориентации. Когда я изменяю ориентацию, состояния фрагментов не сохраняются.

И основная проблема заключается в том, что если у меня открыт FragmentDialog, он просто исчезает.

Я установил setRetainInstance(true); во все фрагменты, но это не помогло.

В моем манифесте я включил android:configChanges="orientation", но по-прежнему не помогает.

Вот мои примеры кода, спасибо за помощь.

public class AddMasterDialog extends DialogFragment {

    private int mTitle;
    private int mPrompt;
    private OnClickListener onSaveListener;
    private OnClickListener onCancelListener;

    public AddMasterDialog newInstance(int title, int prompt) {
        AddMasterDialog simpleDialog = new AddMasterDialog(title, prompt);
        return simpleDialog;
    }

    public AddMasterDialog() {
        // Empty constructor required for DialogFragment
    }
    public AddMasterDialog(int title, int prompt) {
        // Empty constructor required for DialogFragment
        mTitle = title;
        mPrompt = prompt;
    }
    public void setSaveButton(OnClickListener save){
        onSaveListener = save;
    }
    public void setCancelButton(OnClickListener cancel){
        onCancelListener = cancel;
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        //if(savedInstanceState == null){
            View view = inflater.inflate(R.layout.add_new_simple, container);
            getDialog().setTitle(mTitle);
            ((TextView) view.findViewById(R.id.add_simple_new_value_prompt)).setText(mPrompt);

            Button saveButton = (Button) view.findViewById(R.id.add_simple_save_button);
            saveButton.setOnClickListener(onSaveListener);

            //Cancel Button
            Button cancelButton = (Button) view.findViewById(R.id.add_simple_cancel_button);
            cancelButton.setOnClickListener(onCancelListener);
            return view;
        //}
    }
}

и в моей основной деятельности:

private void initiateAddMasterPopupWindow() {
        try {
            addMasterDialog = new AddMasterDialog(R.string.add_new_master_dialog_title, R.string.add_master_new_value_prompt);
            addMasterDialog.setSaveButton(saveNewMasterClickListener);
            addMasterDialog.setCancelButton(cancelNewMasterClickListener);
            FragmentManager fm = getSupportFragmentManager();
            addMasterDialog.show(fm, ADD_NEW_MASTER);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
4b9b3361

Ответ 1

Хорошо, поэтому проблема связана с библиотекой совместимости DialogFragment.

Проблема была описана в этом сообщении.

"Устаревшее сообщение DISMISS для фрагмента сохраняется в очереди сообщений. Оно было поставлено в очередь DialogFragment.onDestroyView() при отмене старого диалога и активируется после создания нового диалога.

Быстрое (и, возможно, грязное) обходное решение состоит в том, чтобы переопределить onDestroyView() и очистить слушателя увольнения до вызова super.onDestroyView() "

Добавление следующего кода в мой DialogFragment решило проблему:

 @Override
 public void onDestroyView() {
     if (getDialog() != null && getRetainInstance()) {
         getDialog().setDismissMessage(null);
     }
     super.onDestroyView();
 }

Ответ 2

В интересах бедной души (я), у которой такая же проблема по разным причинам, я собираюсь опубликовать это. Диалоговое окно диалога должно сохраняться автоматически до тех пор, пока вы выполните следующее:

  • Если вы вызываете Activity onSaveInstanceState(), , убедитесь, что вы вызываете суперфункцию!!!!. В моем случае это был ключ. Также убедитесь, что вы делаете то же самое во Фрагменте.
  • Если вы используете setRetainInstance, вам нужно будет вручную сохранить значения и повторно применить их. В противном случае вы сможете не беспокоиться об этом, в большинстве случаев. Если вы делаете что-то более сложное, вам может понадобиться setRetainInstance(true), но в противном случае игнорировать его. В моем случае мне нужно было использовать его для хранения случайного семестра для одного из моих классов, но в остальном я был в порядке.
  • Некоторые люди жалуются на ошибку в библиотеке поддержки, где отправляется сообщение об увольнении, когда этого не должно быть. Последняя библиотека поддержки, похоже, исправила это, поэтому вам не стоит беспокоиться об этом.

Вам не нужно ничего делать, как вручную хранить фрагмент, это нужно делать автоматически, если вы выполните следующие действия. В целом, это, похоже, делает трюк для всех, у кого есть более современная библиотека поддержки.

Ответ 3

В моем случае у меня был DialogFragment, показывающий другой DialogFragment, используя

listDialogFragment.show(getChildFragmentManager(), "TAG");

Изменение его на

listDialogFragment.show(getActivity().getSupportFragmentManager(), "TAG");

исправлена ​​проблема

Ответ 4

В дополнение к настройке setRetainInstance(true); просто поместите следующий код в DialogFragment. Это проверенное решение.

private boolean isDismissible = false;

@Override
public void dismiss() {

    try {

        isDismissible = true;
        super.dismiss();

        Log.d(getClass().getSimpleName(), "Dialog dismissed!");

    } catch (IllegalStateException ilse) {
    }
}

@Override
public void onDismiss(DialogInterface dialog) {

    // So that dialog should not dismiss on orientation change
    if (isDismissible) {

        // So that dialog can be dismissed
        super.onDismiss(dialog);
    }
}