130

文档dismiss()对类中的方法这么说Dialog

关闭此对话框,将其从屏幕上移除。可以从任何线程安全地调用此方法。请注意,当对话框被关闭时,您不应重写此方法进行清理,而应在onStop().

在我的代码中,我所做的就是调用getDialog().dismiss()将其关闭。但我没有做任何其他事情,甚至没有使用onStop(). 所以我问到底如何正确解除 aDialogFragment以避免任何内存泄漏等。

4

13 回答 13

212

tl; dr:关闭 a 的正确方法DialogFragmentdismiss() 直接在 DialogFragment 上使用。


详细信息DialogFragment状态的文档

对话框的控制(决定何时显示、隐藏、关闭它)应该通过这里的 API 来完成,而不是直接调用对话框。

因此,您不应该使用getDialog().dismiss(),因为这会dismiss() 在 dialog 上调用。相反,您应该使用dismiss()DialogFragment 本身的方法:

公共无效解雇()

关闭片段及其对话框。如果片段被添加到回栈,所有回栈状态直到并包括这个条目都将被弹出。否则,将提交一个新事务以删除该片段。

如您所见,这不仅需要关闭对话框,还需要处理流程中涉及的片段事务。

onStop只有在显式创建任何需要手动清理的资源(关闭文件、关闭游标等)时才需要使用。即使那样,我也会覆盖onStopDialogFragment 而不是onStop底层 Dialog。

于 2012-08-28T15:35:35.933 回答
81

我认为关闭 a 的更好方法DialogFragment是:

Fragment prev = getSupportFragmentManager().findFragmentByTag("fragment_dialog");
if (prev != null) {
    DialogFragment df = (DialogFragment) prev;
    df.dismiss();
}

这样你就不必持有对的引用,DialogFragment并且可以从任何地方关闭它。

于 2014-03-05T01:30:25.270 回答
13

您为什么不尝试仅使用此代码:

dismiss();

如果您想自行关闭对话框片段。您可以简单地将此代码放在要关闭对话框的对话框片段中。

例如:

button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       dismiss();
   }
});

这将关闭屏幕上显示的最近的对话框片段。

希望它对你有帮助。

于 2019-03-14T09:41:06.920 回答
5

我对特雷尔的回答投了赞成票。我只是想为任何 Kotlin 用户发布这个:

supportFragmentManager.findFragmentByTag(TAG_DIALOG)?.let {
    (it as DialogFragment).dismiss()
}
于 2018-10-08T16:56:20.097 回答
5

Kotlin 版本的 Terel 答案

(fragmentManager.findFragmentByTag(TAG) as? DialogFragment)?.dismiss()
于 2018-10-26T09:04:10.817 回答
4

你应该解雇你DialogonPause()所以覆盖它。

同样在解雇之前,您可以检查null并显示如下代码段:

@Override
protected void onPause() {
    super.onPause();
    if (dialog != null && dialog.isShowing()) {
        dialog.dismiss();
    }
}
于 2012-06-26T05:15:15.747 回答
2

在其他答案中有对官方文档(DialogFragment Reference)的引用,但没有提及那里给出的示例:

void showDialog() {
    mStackLevel++;

    // DialogFragment.show() will take care of adding the fragment
    // in a transaction.  We also want to remove any currently showing
    // dialog, so make our own transaction and take care of that here.
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    Fragment prev = getFragmentManager().findFragmentByTag("dialog");
    if (prev != null) {
        ft.remove(prev);
    }
    ft.addToBackStack(null);

    // Create and show the dialog.
    DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
    newFragment.show(ft, "dialog");
}

这将删除任何当前显示的对话框,创建一个带有参数的新 DialogFragment,并将其显示为后堆栈上的新状态。当事务被弹出时,当前的 DialogFragment 及其 Dialog 将被销毁,并重新显示前一个(如果有)。请注意,在这种情况下,DialogFragment 将负责弹出 Dialog 的事务,并与它分开解除。

为了我的需要,我将其更改为:

FragmentManager manager = getSupportFragmentManager();
Fragment prev = manager.findFragmentByTag(TAG);
if (prev != null) {
    manager.beginTransaction().remove(prev).commit();
}

MyDialogFragment fragment = new MyDialogFragment();
fragment.show(manager, TAG);
于 2019-05-04T09:42:18.800 回答
1

我发现当我的片段在导航图中用<fragment>标签定义时(对于全屏对话框片段),对话框片段不会被dismiss()命令关闭。相反,我不得不弹出回栈:

findNavController(getActivity(), R.id.nav_host_fragment).popBackStack();

<dialog>但是,如果在导航图中使用标签定义了相同的对话框片段,则dismiss()可以正常工作。

于 2020-04-27T13:04:58.413 回答
1
CustomFragment dialog = (CustomDataFragment) getSupportFragmentManager().findFragmentByTag("Fragment_TAG");
if (dialog != null) {
  dialog.dismiss();
}
于 2020-05-12T11:08:56.947 回答
1

添加到其他答案中,当进行DialogFragment全屏调用dismiss()时,不会从片段后台堆栈中弹出 DialogFragment。一种解决方法是调用onBackPressed()父活动。

像这样的东西:

CustomDialogFragment.kt

closeButton.onClick {
    requireActivity().onBackPressed()
}
于 2020-05-28T18:51:59.050 回答
0

只需从您要关闭的片段中调用dismiss()。

imageView3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            dismiss();
        }
    });
于 2019-04-26T08:02:50.787 回答
0

考虑下面的示例代码片段,它演示了如何安全地关闭对话框片段:

DialogFragment dialogFragment = new DialogFragment();

/** 
 * do something
 */

// Now you want to dismiss the dialog fragment
if (dialogFragment.getDialog() != null && dialogFragment.getDialog().isShowing())
{
    // Dismiss the dialog
    dialogFragment.dismiss();
}

快乐编码!

于 2020-12-16T11:49:37.367 回答
0

这是一个简单的 AppCompatActivity 扩展函数,它关闭打开的 Dialog Fragment:

fun AppCompatActivity.whenDialogOpenDismiss(
    tag: String
) {
    supportFragmentManager.findFragmentByTag(tag)?.let { 
        if(it is DialogFragment) it.dismiss() }
}

当然,您可以直接从任何活动中调用它。如果您需要从 Fragment 调用它,只需对 Fragment 类进行相同的扩展功能

于 2021-01-14T18:14:54.313 回答