8

我有一个 DialogDragment 可以显示以下两种方式之一:

1)通过从其 OnItemClickListener 中点击 ListView 项目

2) 通过激活 ListView 的上下文菜单并选择一个菜单项

执行 #1 在所有生命周期事件下都可以正常工作,但是如果我通过 #2 调用它并暂停活动(通过返回主页)并通过任务切换器恢复它,则不再显示对话框。片段就在那里,我可以旋转设备并显示对话框。

我进行了实验,如果我将 DialogFragment 的显示放入一个延迟至少 1/2 秒的 Handler 中,它就可以工作。

以下片段失败 - 它显示对话框,但随后暂停/恢复隐藏它:

public boolean onContextItemSelected(android.view.MenuItem item) {
    boolean consumed = false;

    switch (item.getItemId()) {
    case R.id.menu_item:
        showMyDialogFragment();
        consumed = true;
        break;
    }

    return consumed;
}

所以下面的代码片段有效。暂停/恢复再次正确显示对话框:

public boolean onContextItemSelected(android.view.MenuItem item) {
    boolean consumed = false;

    switch (item.getItemId()) {
    case R.id.menu_item:
        new Handler().postDelayed(new Runnable() {
            public void run() {
                showMyDialogFragment();
            }
        }, 300);

        consumed = true;
        break;
    }

    return consumed;
}

用 0 毫秒或 250 毫秒的延迟替换 300 毫秒的秒延迟会导致它再次被破坏。这可重复 100% 的时间。

这显然是一个可怕的黑客攻击,可能取决于设备速度的常数使情况变得更糟。

有人知道为什么会这样和/或提供更好的解决方案吗?我在这个问题上花了几个小时,这是我能想到的最好的。

4

2 回答 2

4

我可以在 Android 4.2(ARM 模拟器和 Galaxy Nexus)上重现这个。我无法在 x86 4.1 模拟器、Nexus S (4.1) 和 Motorola RAZR i (4.0) 上重现您的发现。我还可以通过修改我自己的一本图书样本来重现该问题。我使用您的示例提交了一个问题:http ://code.google.com/p/android/issues/detail?id=41901请添加您认为有助于他们诊断问题的任何其他信息。

关于解决方法,如果 300 毫秒有效,那么我们有一个可爱的“时间问题”,我不知道你会如何解决它,除非不使用菜单来显示它。例如,对于您的示例应用程序,只需切换到SHOW_AS_ACTION_ALWAYS(因此使其成为操作栏上的项目而不是溢出菜单中的项目)就足以使DialogFragment行为正常。希望您有办法调整您的 UI 以弥补此错误,或者也许有人会提出另一种解决方法并将其发布在此处或问题上。

于 2012-12-25T19:39:30.487 回答
2

我建议在所有暂停时销毁对话框,并根据状态在 onResume 中重新创建,而不管如何调用对话框。如果应用程序在暂停时被操作系统杀死,否则这样做可能会导致内存泄漏。

要明确回答您的问题,请不要依赖操作系统来维护您的应用程序状态。

于 2012-12-24T01:23:12.840 回答