15

I have a question regarding DialogFragment. I am trying to make a dialog that keeps it's state after the device is rotated. This dialog has a bunch of references to things such as adapters and other heavier objects and I need this to be kept upon rotation, if possible without having to make every reference Parcelable or Serializable in order for me to use onSaveInstanceState to save and restore them when the original activity is re-created.

I've noticed there's a method called setRetainInstance(boolean) on the DialogFragment which allows you to keep the dialog fragment instance when the activity is re-created. However, when I rotate the device now, the dialog is not showing anymore. I know I can get it from the activity's FragmentManager, but I cannot find a way to make it visible again. Any suggestions on this?

Thanks, Mihai

John Powell
  • 12,253
  • 6
  • 59
  • 67
r1k0
  • 1,406
  • 1
  • 11
  • 26
  • 1
    Perhaps this can help: http://stackoverflow.com/questions/8235080/fragments-dialogfragment-and-screen-rotation – Gunnar Karlsson Dec 18 '12 at 14:29
  • I see a much bigger conceptual problem here. In the android docs for setFragmentInstance it is written that "Control whether a fragment instance is retained across Activity re-creation (such as from a configuration change). This can only be used with **fragments not in the back stack**. If set, the fragment lifecycle will be slightly different when an activity is recreated". Is this thing due to the fact that the dialog fragment is in the backstack? – Swapnil Jan 12 '17 at 17:50

2 Answers2

24

There are few things you need to do :

  1. use instance factory method to initiate a DialogFragment instance like this :

    public static MyDialogFragment newInstance(MyModel model) {
        MyDialogFragment myDialogFragment = new MyDialogFragment();
        Bundle bundle = new Bundle();
        bundle.putSerializable("MODEL", model);
        myDialogFragment .setArguments(bundle);
        return myDialogFragment;
    }
    
  2. by putting setRetainInstance(true) in onCreate, all of your references declared in the fragment will be kept after the original activity is re-created

    @Override
    public void onCreate(Bundle icicle) {
        this.setCancelable(true);
        setRetainInstance(true);
        super.onCreate(icicle);
    
    }
    
  3. avoiding disappear on rotation by doing this

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

    }

  4. get your object by using

    (MyModel) getArguments().getSerializable("MODEL")
    
ricky888
  • 696
  • 6
  • 7
  • Thanks for the answer @ricky888, but since I am creating a dialog fragment instance and passing stuff in the constructor of the dialog fragment, such as list adapters and other heavy data, I wanted to avoid serialization and I was thinking of using set retain instance state so that the dialog fragment doesn't get re-created upon rotation. So, I thought that by using set retain instance state, I will have the same dialog fragment as before the rotation - meaning that the dialog fragment did not get re-created with the activity and its fragments upon rotation. Is this the case? – r1k0 Jan 04 '13 at 10:33
  • setRetainInstance - Control whether a fragment instance is retained across Activity re-creation (such as from a configuration change). So the answer is yes. You will keep the same instance of all your stuffs across the rotation by simply putting them in the bundle just as I mentioned above. – ricky888 Jan 06 '13 at 16:51
  • Indeed the correct answer would involve the serialization, so we re-designed the fragment to be less data intensive in order to be able to persist it's state upon configuration changes, as suggested by @ricky888 – r1k0 Dec 05 '13 at 10:05
0

The dialog fragment should be preserved automatically as long as you do the following:

  1. If you call an Activity onSaveInstanceState(), make sure you call the super function!!!!. In my case, that was the key. Also make sure you do the same thing in the Fragment.
  2. If you use setRetainInstance, you need to manually store off the values. Otherwise, you should be able to not worry about it, in most cases. If you're doing something a bit more complicated, you might need to setRetainInstance(true), but otherwise ignore it.
  3. Some people have complained about a bug in the support library, where a dismiss message is sent when it shouldn't be. The latest support library seems to have fixed that, so you shouldn't need to worry about that.
PearsonArtPhoto
  • 38,970
  • 17
  • 111
  • 142
  • 2
    About #2 , I think you meant "if you don't use setRetainInstance ..." in the beginning of the sentence, because otherwise you'd have to store&restore the values. – android developer Mar 26 '15 at 10:50