我有一个DialogFragment,我在用户点击ActionBar上的菜单项时启动。关于Dialog的所有功能都能正常运行 - 它启动得很好,并且它完成了我设置的所有功能。不幸的是,只要我旋转设备,DialogFragment就会消失。
这似乎是2012年的一个常见问题 - 我已经搜索了StackOverflow,并尝试了过去几年发布的所有常见修复程序。 This SO post in particular总结了所有已提出的潜在修复方法:
setRetainInstance(true)
添加到DialogFragment' s onCreate()
onDestroyView()
添加解决方法以解决支持库中的潜在错误尽管实现了上述所有内容,但DialogFragment拒绝在设备轮换后坚持下去。
以下是我如何从Activity:
启动DialogFragmentDialogKanjiLookup dialog = DialogKanjiLookup.newInstance(gSearchView.getQuery());
dialog.show(getSupportFragmentManager(), "dialogKanjiLookup");
这是DialogFragment' 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;
}
这里是对话框的'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;
}
只有一个DialogFragment.dismiss()
的实例在片段中调用,但只有在用户点击其中一个对话框的按钮时才会触发,所以我已经排除了这一点。为什么我的DialogFragment在轮换后仍然消失?我只是把头发拉过来,它在我implemented a Navigation Drawer之后的某个时候工作正常。这可能是问题的一部分吗?
编辑:误报,我发现我的答案不是解决方案!在我完成将所有碎片和活动从使用支持库移开后,问题再次出现。
我 发现此问题仅存在于活动布局中内容片段未已静态声明的活动中。也就是说,如果我在XML中定义<FrameLayout>
并使用fragmentManager.beginTransaction().replace(R.id.content_frame, frag, tag).commit();
加载片段,则在旋转设备时,在该活动中启动的任何DialogFragments都无法重新加载。
这是一个演示此问题的屏幕录制: https://www.youtube.com/watch?v=psK0pzMn6oc
答案 0 :(得分:0)
经过一些实验,我发现了一个解决方案。启动对话框的活动需要扩展android.support.v4.app.FragmentActivity
,而 DialogFragment 需要扩展android.support.v4.app.DialogFragment
。
然后,在启动 DialogFragment 时必须调用getSupportFragmentManager()
:
CustomDialog dialog = CustomDialog.newInstance();
dialog.show(getSupportFragmentManager(), "customDialog");
这应该在旋转期间保留对话框。 没有需要在对话框中使用setRetainInstance(true)
。
请注意,这仅适用于FragmentActivity
调用DialogFragment
的情况。我仍然试图找出一种方法来保留一个通过Fragment调用的对话框。