【问题标题】:DialogFragment disappears after device rotation despite applying common fixes尽管应用了常见修复,DialogFragment 在设备旋转后消失
【发布时间】:2014-03-12 17:29:59
【问题描述】:

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

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

  • 设置 DialogFragment 以使用 newInstance() 范例
  • setRetainInstance(true) 添加到DialogFragment 的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

【问题讨论】:

  • 您是否尝试过使用example pattern 显示此内容?也就是说,调用dialog.show(fragmentTransaction, tag) 而不是show(fragmentManager, tag)。这些是slightly different things
  • Alert Dialog 部分下,它们以与我现在相同的方式显示自定义 DialogFragment。我尝试使用 FragmentTransaction 调用show(),但它没有改变任何东西。
  • 啊,确实如此。您是否尝试过在您的活动/片段上下文中仅显示一个简单的“Hello World”对话框并确保它在旋转后保持不变?如果这不起作用(类似于this),那么在其他地方恢复状态可能存在问题。
  • @AdamS 嗯,我刚刚实现了您的示例对话框,当应用程序旋转时它也消失了。我想这意味着问题不在于对话框,而在于 Activity 本身。
  • 我目前支持 APK 14 及更高版本,所以我认为(为了我的理智)我将检查我的代码并尽可能多地从 v4 支持库迁移出去。

标签: android android-dialogfragment android-orientation


【解决方案1】:

经过一些实验,我发现了一个解决方案。启动对话框的Activity需要扩展android.support.v4.app.FragmentActivityDialogFragment需要扩展android.support.v4.app.DialogFragment

那么,在启动DialogFragment时必须调用getSupportFragmentManager()

CustomDialog dialog = CustomDialog.newInstance();
dialog.show(getSupportFragmentManager(), "customDialog");

这应该在旋转期间保留对话框。 没有需要在对话框本身中使用setRetainInstance(true)

请注意,这只适用于FragmentActivity 调用DialogFragment 的情况。我仍在尝试寻找一种方法来保留通过 Fragment 调用的对话框。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-21
    • 2023-03-24
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多