DialogFragment/переключатель ориентации

У меня есть довольно простой DialogFragment. Это выглядит примерно так:

import android.support.v4.app.DialogFragment;

public class MyDialogFragment extends DialogFragment {

    private String mData = "empty";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(LOG_TAG, "onCreate");

        setStyle(DialogFragment.STYLE_NO_TITLE, 0);
        // setRetainInstance(true);
    }

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

        View view = inflater.inflate(R.layout.mydialog, container);

        ....

        return view;
    }

    public setData(String _data) {
        mData = _data;
    }
}

Я загружаю этот фрагмент вот так из моего FragmentActivity:

FragmentManager lFM = getSupportFragmentManager();
MyDialogFragment lDialog = new MyDialogFragment();
lDialog.setData("not empty");
lDialog.show(lFM, "MyDialog");

Код, как указано выше, работает нормально. Однако я хотел бы сохранить фрагмент на переключателе ориентации, чтобы сохранить поле mData. Если я добавлю setRetainInstance(true); (и после некоторой отладки), я увижу, что фрагмент действительно сохраняется при переключении ориентации - onCreate() на этот раз не вызывается. Я вижу, что вызывается onCreateView(), и я возвращаю правильный объект View, но диалоговое окно не отображается на экране. Что мне не хватает?


person Lieuwe    schedule 30.01.2013    source источник
comment
какова ваша активность android:configChanges в манифесте?   -  person baboo    schedule 30.01.2013
comment
Он не установлен — мое приложение само не обрабатывает изменения конфигурации. В любом случае я предпочитаю, чтобы моя активность перезапускалась при изменении ориентации - проблема в том, что мой фрагмент (правильно) сохраняется, но не отображается.   -  person Lieuwe    schedule 30.01.2013
comment
По возможности избегайте использования android:configChanges, Google не рекомендует это делать!   -  person    schedule 31.01.2013


Ответы (3)


Попробуйте следующую логику в своей активности фрагмента:

Используйте методы put для хранения значений в onSaveInstanceState():

protected void onSaveInstanceState(Bundle icicle) {
  super.onSaveInstanceState(icicle);
  icicle.putBoolean("dialogDisplayed", value);    // set value = true when displayin dialog...
}

И восстановите значения в onCreate():

 public void onCreate(Bundle icicle) {
   if (icicle != null){
     value = icicle.getBoolean("dialogDisplayed");
   }
   if(value)
       //Display Dialog here.... 

 }
person baboo    schedule 31.01.2013
comment
Не забудьте проверить значение null в onSaveInstanceState() - person ; 31.01.2013
comment
Реализовано немного по-другому, но я приму ответ - спасибо - person Lieuwe; 04.02.2013
comment
Это ничего не делает, когда вы знаете, что диалоговое окно показано. Вам нужен экземпляр диалога, чтобы отклонить. - person nyconing; 26.04.2017

Прочитав ответ, который дал мне бабу, я реализовал решение следующим образом. Надеюсь, это правильно (по крайней мере, все работает нормально...)

@Override
public void onCreate(Bundle savedInstanceState) {

  // ....

  FragmentManager lFM = getSupportFragmentManager();
  if(lFM.findFragmentByTag("MyDialog")!=null)
    ((MyDialogFragment)lFM.findFragmentByTag("MyDialog")).show(lFM, "MyDialog");

  // ....
}
person Lieuwe    schedule 04.02.2013

Фрагмент диалога должен сохраняться автоматически, пока вы делаете следующее:

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

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

person PearsonArtPhoto    schedule 31.12.2013