文档dismiss()
对类中的方法这么说Dialog
:
关闭此对话框,将其从屏幕上移除。可以从任何线程安全地调用此方法。请注意,当对话框被关闭时,您不应重写此方法进行清理,而应在
onStop()
.
在我的代码中,我所做的就是调用getDialog().dismiss()
将其关闭。但我没有做任何其他事情,甚至没有使用onStop()
. 所以我问到底如何正确解除 aDialogFragment
以避免任何内存泄漏等。
文档dismiss()
对类中的方法这么说Dialog
:
关闭此对话框,将其从屏幕上移除。可以从任何线程安全地调用此方法。请注意,当对话框被关闭时,您不应重写此方法进行清理,而应在
onStop()
.
在我的代码中,我所做的就是调用getDialog().dismiss()
将其关闭。但我没有做任何其他事情,甚至没有使用onStop()
. 所以我问到底如何正确解除 aDialogFragment
以避免任何内存泄漏等。
tl; dr:关闭 a 的正确方法DialogFragment
是dismiss()
直接在 DialogFragment 上使用。
详细信息:DialogFragment状态的文档
对话框的控制(决定何时显示、隐藏、关闭它)应该通过这里的 API 来完成,而不是直接调用对话框。
因此,您不应该使用getDialog().dismiss()
,因为这会dismiss()
在 dialog 上调用。相反,您应该使用dismiss()
DialogFragment 本身的方法:
公共无效解雇()
关闭片段及其对话框。如果片段被添加到回栈,所有回栈状态直到并包括这个条目都将被弹出。否则,将提交一个新事务以删除该片段。
如您所见,这不仅需要关闭对话框,还需要处理流程中涉及的片段事务。
onStop
只有在显式创建任何需要手动清理的资源(关闭文件、关闭游标等)时才需要使用。即使那样,我也会覆盖onStop
DialogFragment 而不是onStop
底层 Dialog。
我认为关闭 a 的更好方法DialogFragment
是:
Fragment prev = getSupportFragmentManager().findFragmentByTag("fragment_dialog");
if (prev != null) {
DialogFragment df = (DialogFragment) prev;
df.dismiss();
}
这样你就不必持有对的引用,DialogFragment
并且可以从任何地方关闭它。
您为什么不尝试仅使用此代码:
dismiss();
如果您想自行关闭对话框片段。您可以简单地将此代码放在要关闭对话框的对话框片段中。
例如:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
这将关闭屏幕上显示的最近的对话框片段。
希望它对你有帮助。
我对特雷尔的回答投了赞成票。我只是想为任何 Kotlin 用户发布这个:
supportFragmentManager.findFragmentByTag(TAG_DIALOG)?.let {
(it as DialogFragment).dismiss()
}
Kotlin 版本的 Terel 答案
(fragmentManager.findFragmentByTag(TAG) as? DialogFragment)?.dismiss()
你应该解雇你Dialog
,onPause()
所以覆盖它。
同样在解雇之前,您可以检查null
并显示如下代码段:
@Override
protected void onPause() {
super.onPause();
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
}
在其他答案中有对官方文档(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);
我发现当我的片段在导航图中用<fragment>
标签定义时(对于全屏对话框片段),对话框片段不会被dismiss()
命令关闭。相反,我不得不弹出回栈:
findNavController(getActivity(), R.id.nav_host_fragment).popBackStack();
<dialog>
但是,如果在导航图中使用标签定义了相同的对话框片段,则dismiss()
可以正常工作。
CustomFragment dialog = (CustomDataFragment) getSupportFragmentManager().findFragmentByTag("Fragment_TAG");
if (dialog != null) {
dialog.dismiss();
}
添加到其他答案中,当进行DialogFragment
全屏调用dismiss()
时,不会从片段后台堆栈中弹出 DialogFragment。一种解决方法是调用onBackPressed()
父活动。
像这样的东西:
CustomDialogFragment.kt
closeButton.onClick {
requireActivity().onBackPressed()
}
只需从您要关闭的片段中调用dismiss()。
imageView3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
}
});
考虑下面的示例代码片段,它演示了如何安全地关闭对话框片段:
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();
}
快乐编码!
这是一个简单的 AppCompatActivity 扩展函数,它关闭打开的 Dialog Fragment:
fun AppCompatActivity.whenDialogOpenDismiss(
tag: String
) {
supportFragmentManager.findFragmentByTag(tag)?.let {
if(it is DialogFragment) it.dismiss() }
}
当然,您可以直接从任何活动中调用它。如果您需要从 Fragment 调用它,只需对 Fragment 类进行相同的扩展功能