问题
I have a DialogFragment that I launch when a user taps a menu item on the ActionBar. Everything about the Dialog functions properly - it launches just fine and it does everything I've set it up to do. Unfortunately, as soon as I rotate my device, the DialogFragment disappears.
This seemed to be a common problem back in 2012 - I've scoured StackOverflow and tried all of the common fixes that have been posted in the last couple of years. This SO post in particular summarizes all of the potential fixes that have been proposed:
- Set up the DialogFragment to use the newInstance() paradigm
- Add
setRetainInstance(true)
to the DialogFragment'sonCreate()
- Add a workaround to
onDestroyView()
to address a potential bug in the support library
Despite implementing everything above, the DialogFragment refuses to stick around after device rotation.
Here's how I launch the DialogFragment from the Activity:
DialogKanjiLookup dialog = DialogKanjiLookup.newInstance(gSearchView.getQuery());
dialog.show(getSupportFragmentManager(), "dialogKanjiLookup");
Here is the DialogFragment's newInstance()
:
public DialogKanjiLookup() {}
public static DialogKanjiLookup newInstance(CharSequence searchTerm)
{
DialogKanjiLookup dialog = new DialogKanjiLookup();
Bundle args = new Bundle();
args.putCharSequence(BUNDLE_SEARCH, searchTerm);
dialog.setArguments(args);
return dialog;
}
Here's the dialog's `onCreateDialog():
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
// Specify a layout for the dialog
LayoutInflater inflater = getActivity().getLayoutInflater();
View layout = inflater.inflate(R.layout.dialog_kanjilookup, null);
// SNIP
// ...Handle savedInstanceState, set up various Listeners and adapters...
// SNIP
// Create the actual dialog
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Customize the dialog
builder.setTitle(R.string.dialog_kanji_lookup_title);
builder.setIcon(R.drawable.kanji_lookup);
builder.setPositiveButton(R.string.menu_search, btnSearchListener);
builder.setNegativeButton(R.string.cancel, null);
builder.setView(layout);
// Force the dialog to take up as much space as it can
Dialog dialog = builder.create();
dialog.show();
dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
// Display the dialog
return dialog;
}
There's only one instance of DialogFragment.dismiss()
called from within the fragment but that's only triggered when the user taps one of the dialog's buttons, so I've ruled that out. Why does my DialogFragment still disappear after rotation? I'm all but pulling my hair out over this, it worked fine until sometime after I implemented a Navigation Drawer. Could that be a part of the problem?
EDIT: False alarm, I discovered that my answer wasn't the solution! The problem reappeared after I finished moving all of my Fragments and Activities away from using the Support Libraries.
I did discover that this problem only exists in Activities in which the content fragment has not been declared statically in the Activity's layout. That is, if I have a <FrameLayout>
defined in XML and use fragmentManager.beginTransaction().replace(R.id.content_frame, frag, tag).commit();
to load a fragment, any DialogFragments launched in that activity fail to reload when the device has been rotated.
Here's a screen recording that demonstrates the issue: https://www.youtube.com/watch?v=psK0pzMn6oc
回答1:
After some experimentation I discovered a solution. The Activity that launches the dialog needs to extend android.support.v4.app.FragmentActivity
, and the DialogFragment needs to extend android.support.v4.app.DialogFragment
.
Then, getSupportFragmentManager()
must be called when launching the DialogFragment:
CustomDialog dialog = CustomDialog.newInstance();
dialog.show(getSupportFragmentManager(), "customDialog");
This should retain the dialog during rotation. There was no need to use setRetainInstance(true)
in the dialog itself.
Mind you, this only works in instances in which an FragmentActivity
calls a DialogFragment
. I'm still trying to suss out a way to preserve a dialog that gets called via a Fragment instead.
来源:https://stackoverflow.com/questions/22359381/dialogfragment-disappears-after-device-rotation-despite-applying-common-fixes