Search code examples
androidandroid-alertdialogandroid-dialogfragmentsavestate

Change layout and save state in DialogFragment on configuration changed


I have a DialogFragment which holds custom AlertDialog with a custom view.

And there is a problem, on orientation change. It's needed:

  1. Save dialog state (state of views in custom view in AlertDialog) if needed.
  2. Change the alert dialog's layout and its size;

When activity is recreating on rotate everything is fine, it's enough to implement AlertDialog.onSaveInstanceState() and AlertDialog.onRestoreInstanceState() and DialogFragment will do the rest.

The problem is when activity is NOT recreating on orientation change, but it's still needed to do two steps described above. The perfect solution will be to encapsulate that logic inside of derived AlertDialog or DialogFragment, so the users who will use that dialog will not worry for anything.


What I've tried so far.

  1. Easy way. Do not recreate the dialog.

We can figure out that orientation was changed either implementing ViewTreeObserver.OnGlobalLayoutListener() in our AlertDialog or in DialogFragment.onConfigurationChanged(). At this moment, I was trying to save state, reinflate view and call AlertDialog.setView(). It's not working. The state is saving, dialog size is changing, but the view is remaining the old view. I don't know why, maybe it's not allowed to reinflate the view when the dialog is showing.

  1. Dismiss dialog, recreate, show again.

I was trying to do something like that. In DialogFragment:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    dismiss();
    show(getFragmentManager(), getTag());
}

So hide, recreate dialog, show again. And it works!

But. If I:

  1. Open dialog
  2. Go to the home screen (hide application)
  3. onSaveInstanceState method of Activity and DialogFragment is called.
  4. Rotate device
  5. Restore application
  6. DialogFragment.onConfigurationChanged() will be called and if I try to call here dismiss() or show() this time, I'll receive "Can not perform this action after onSaveInstanceState" because at this moment activity is not actually restored.

And I don't see the right place to do something like that.


So, any other things to try?


Solution

  • If i correctly understand your problem, you want to have different layout for landscape/portrait orientations? If yes, and your activity is not recreating because of manifest configChanges = orientation you have onConfigurationChanged callback to handle anything i.e. your layout changes.

    While creating your custom dialog, you probably are using setContentView(View view).

    So while creating your dialog for the first time set some content view which is only general container like FrameLayout etc.

    Then create method which is inflating your internal layout with all content that you want ot show and add it dynamically to your container FrameLayout. When orientation changes... remove internal layout, inflate it once again with different orientation and add once again.