如何正确解雇DialogFragment?

问题描述 投票:102回答:8

文档为dismiss()类的Dialog方法说这个:

关闭此对话框,将其从屏幕上删除。可以从任何线程安全地调用此方法。请注意,在关闭对话框时不应覆盖此方法以进行清理,而是在onStop()中实现该方法。

在我的代码中,我所做的只是调用getDialog().dismiss()来解雇它。但我没有做任何其他事情甚至使用onStop()。所以我问到究竟如何正确解雇DialogFragment以避免任何内存泄漏等。

android android-dialogfragment
8个回答
174
投票

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


详情:documentation of DialogFragment

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

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

public void dismiss()

关闭片段及其对话框。如果片段被添加到后台堆栈,则将弹出所有后台堆栈状态,包括此条目。否则,将提交新事务以删除该片段。

正如您所看到的,这不仅关闭对话框,还关注处理流程中涉及的片段事务。

如果您明确创建了需要手动清理的任何资源(关闭文件,关闭游标等),则只需使用onStop。即使这样,我也会覆盖DialogFragment的onStop而不是底层Dialog的onStop


65
投票

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

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

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


3
投票

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

dismiss();

如果你想自己解除Dialog Fragment。您可以简单地将此代码放在要取消Dialog的对话框片段中。

例如:

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

这将关闭屏幕上显示的最近的Dialog Fragment。

希望它对你有所帮助。


2
投票

你应该在Dialog解雇你onPause(),所以覆盖它。

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

@Override
protected void onPause() {
    super.onPause();
    if (dialog != null && dialog.isShowing()) {
        dialog.dismiss();
    }
}

2
投票

我对Terel的答案给予了支持。我只是想为任何Kotlin用户发布这个:

supportFragmentManager.findFragmentByTag(TAG_DIALOG)?.let {
    (it as DialogFragment).dismiss()
}

2
投票

Kotlin版本的Terel回答

(fragmentManager.findFragmentByTag(TAG) as? DialogFragment)?.dismiss()

0
投票

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

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

0
投票

在其他答案中有官方文档(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);
© www.soinside.com 2019 - 2024. All rights reserved.