DialogFragment无法关闭

3

我找了很多解决方案,但好像这不是一个常见的问题。

我想在应用连接到服务器时显示一个不确定的对话框旋转器,然后清除该对话框并在请求完成后显示另一个对话框。我正在使用Fragment兼容包。问题是,在显示第二个对话框之前,旋转器没有被移除。

以下是显示对话框并应该移除任何当前对话框的代码:

void displayDialog(int type, String message) {
    Log.i(logTag, "displayDialog: " + type);
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
    if (prev != null) {
        Log.i(logTag, "removing previous dialog");
        ft.remove(prev); //TODO maybe use ((DialogFragment)dialog).dismiss(); ?
    }
    ft.addToBackStack(null);

    // Create and show the dialog.
    DialogFragment newFragment = DialogHelperFragment.newInstance(type, message);
    newFragment.show(ft, "dialog");
}

这是我用来排查此 bug 的调用代码:

displayDialog(DialogHelperFragment.DIALOG_PROGRESS, null);
displayDialog(DialogHelperFragment.DIALOG_PURCHASE_SUCCESS, null);

以下是我对应的LogCat输出:

这里是我的对应LogCat输出:

06-25 13:53:35.497: I/tag(11008): displayDialog: 8
06-25 13:53:35.497: I/tag(11008): displayDialog: 7
06-25 13:53:35.897: I/tag Dialog Helper(11008): Creating Dialog: 8
06-25 13:53:35.907: I/tag Dialog Helper(11008): Creating Dialog: 7

问题在于:
Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");

返回null是因为第一个对话框在调用displayDialog()时尚未创建或附加。

任何提示都将非常有帮助。


只是觉得值得添加一个链接,因为它类似但不完全相同:https://dev59.com/o27Xa4cB1Zd3GeqPmiif#18187157 - TacB0sS
2个回答

7

我需要的是

getSupportFragmentManager().executePendingTransactions()

就像这里所示。似乎事务并不急于进行。此调用可以加快事务的进行。现在我的事务顺序如下:

06-26 10:45:43.800: I/tag(3303): displayDialog: 8
06-26 10:45:43.800: I/tag(3303): Previous Dialog Fragment is:null
06-26 10:45:43.810: I/tag(3303): displayDialog: 7
06-26 10:45:43.810: I/tag(3303): Previous Dialog Fragment is:DialogHelperFragment{40b44a78 #0 dialogHelp}
06-26 10:45:43.810: I/tag(3303): removing previous dialog
06-26 10:45:44.220: I/tag Dialog Helper(3303): Creating Dialog: 7

因此,在实际创建之前,对话框类型8已被删除。

希望这能帮助那些遇到同样问题的人。

编辑

看来我还必须删除addToBackStack(null)


1

很抱歉,我并没有深入研究你的代码,但是我在你的FragmentTransaction中找不到“commit”调用。最后你需要提交这些事务。

编辑:既然你正在使用DialogFragments,它可以通过show和dismiss自行管理事务,因此你应该利用它来代替。

不过,你仍然需要对Fragment的Dialog对象调用dismiss。


从Android文档的DialogFragment.show(FragmentTransaction,String)中: "显示对话框,使用现有的事务添加片段,然后提交该事务。"在我看来,show()为我提交了事务。 - Mike T
是的,你说得对。当你回复时,我已经在我的答案中添加了另一个想法。 - tiguchi
在其他人身上,直接在对话框上调用dismiss()并没有起作用,而且在其他SO帖子上的普遍感觉是在DialogFragment上调用dismiss()更好。这就是我为我的警报DialogFragments所做的,但不确定的微调器需要在何时通知被解雇。如果当getSupportFragmentManager().findFragmentByTag("dialog");返回null时,您无法掌握片段的处理方式是什么? - Mike T
1
首先,您可以为这两个不同的对话框分配单独的标签,以便您可以区分它们并检索和关闭正确的对话框。或者,您可以保留对这些片段的引用。或者,在旋转对话框可见后(DialogFragment.onStart),您可以开始与服务器通信。 - tiguchi
我喜欢在对话框可见后开始服务器通信的想法。但目前我正在努力让 getSupportFragmentManager().findFragmentByTag("dialog"); 返回除 null 以外的任何内容... - Mike T
我找到了更好的解决方案。我会将其发布为答案,并因你的帮助而点赞。 - Mike T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接