尽管应用了常见的修复,但在设备旋转后DialogFragment会消失

时间:2014-03-12 17:30:00

标签: android android-dialogfragment android-orientation

我有一个DialogFragment,我在用户点击ActionBar上的菜单项时启动。关于Dialog的所有功能都能正常运行 - 它启动得很好,并且它完成了我设置的所有功能。不幸的是,只要我旋转设备,DialogFragment就会消失。

这似乎是2012年的一个常见问题 - 我已经搜索了StackOverflow,并尝试了过去几年发布的所有常见修复程序。 This SO post in particular总结了所有已提出的潜在修复方法:

  • 设置DialogFragment以使用newInstance()范例
  • setRetainInstance(true)添加到DialogFragment' s onCreate()
  • onDestroyView()添加解决方法以解决支持库中的潜在错误

尽管实现了上述所有内容,但DialogFragment拒绝在设备轮换后坚持下去。

以下是我如何从Activity:

启动DialogFragment
DialogKanjiLookup 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

1 个答案:

答案 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调用的对话框。