I'm implementing a dialog with two EditText
fields. According to the Material Design specs, this kind of dialog should be shown fullscreen on smaller devices whereas on large screens it should be shown in a dialog window.
To achieve this, I've followed the implementation from the developer.android.com guide on Dialogs.
This works fine for smaller screens but for large screens the dialog window occupies the full screen after an orientation change.
Code for showing the DialogFragment
(part of onOptionsItemSelected()
in my AppCompatActivity
)
mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
FragmentManager fragmentManager = getSupportFragmentManager();
mDialog = MyDialogFragment.newInstance(mIsLargeLayout);
if (mIsLargeLayout)
{
// The device is using a large layout, so show the fragment as a dialog
mDialog.show(fragmentManager, "dialog");
}
else
{
// The device is smaller, so show the fragment fullscreen
FragmentTransaction transaction = fragmentManager.beginTransaction();
// To make it fullscreen, use the 'content' root view as the container
// for the fragment, which is always the root view for the activity
transaction.add(android.R.id.content, mDialog, "dialog")
.addToBackStack(null)
.commit();
}
For the DialogFragment
, I override first onCreateView()
to inflate my custom layout:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
setStyle(DialogFragment.STYLE_NORMAL, R.style.AppTheme);
View v = inflater.inflate(R.layout.dialog_filter_audio_files,
container, false);
// code for Buttons and EditTexts here:
// set listeners etc.
return v;
}
... and then onCreateDialog()
with the following statements:
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setCancelable(true);
dialog.getWindow().setBackgroundDrawableResource(R.color.c_background_dark);
return dialog;
I don't dismiss the DialogFragment
on orientation change but in onRestoreInstanceState()
I reconnect to the DialogFragment
like this:
mDialog = (DialogFilterAudiofiles) getSupportFragmentManager().findFragmentByTag("dialog");
While the user is able to complete the dialog no matter what it looks like, I'd like to keep the dialog small - just like it was before the orientation change.
Of course I could dismiss the dialog in onSaveInstanceState()
after saving the input so far and then show a new dialog in onRestoreInstanceState()
.
Or I could work with DialogFragment
s based on AlertDialog
and setContentView()
if the screen size is large.
Is there another way to fix the sample code from the guide?
EDIT I'd like to stay as close as possible to the "one layout fits all sizes" approach.
My implementation of "onCreateView()" is inspired by but extending the sample code, so I've added the relevant part in the text above.
I finally found the source of the problem:
setStyle(DialogFragment.STYLE_NORMAL, R.style.AppTheme);
works fine at first: the DialogFragment
is created as a full screen dialog or in a small window, depending on the value of mIsLargeLayout
.
BUT if it has to be recreated after a configuration change, this line causes it to appear fullscreen.
My expectation had been that the value R.style.AppTheme
would make the runtime look up the custom dialog style which was part of the app theme, but in fact it just treated the DialogFragment
as a kind of Activity
when re-creating after a configuration change.
In my case, dropping the whole statement worked as well as using
setStyle(DialogFragment.STYLE_NORMAL, 0);
From the documentation for the second parameter:
Optional custom theme. If 0, an appropriate theme (based on the style) will be selected for you.