Android 如何正确关闭 DialogFragment?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11201022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to correctly dismiss a DialogFragment?
提问by Andy
The docs say this for the dismiss()
method from the Dialog
class:
文档dismiss()
对Dialog
类中的方法是这样说的:
Dismiss this dialog, removing it from the screen. This method can be invoked safely from any thread. Note that you should not override this method to do cleanup when the dialog is dismissed, instead implement that in
onStop()
.
关闭此对话框,将其从屏幕上移除。可以从任何线程安全地调用此方法。请注意,当对话框关闭时,您不应覆盖此方法来进行清理,而是在
onStop()
.
In my code, all I do is call getDialog().dismiss()
to dismiss it. But I am not doing anything else or even using onStop()
. So I am asking exactly how to correctly dismiss a DialogFragment
to avoid any memory leaks, etc..
在我的代码中,我所做的就是调用getDialog().dismiss()
关闭它。但我没有做任何其他事情,甚至没有使用onStop()
. 所以我问的是如何正确地解除 aDialogFragment
以避免任何内存泄漏等。
回答by Heinzi
tl;dr:The correct way to close a DialogFragment
is to use dismiss()
directly on the DialogFragment.
tl;dr:关闭 a 的正确方法DialogFragment
是dismiss()
直接在 DialogFragment 上使用。
Details: The documentation of DialogFragmentstates
详细信息:DialogFragment状态的文档
Control of the dialog (deciding when to show, hide, dismiss it) should be done through the API here, not with direct calls on the dialog.
对话框的控制(决定何时显示、隐藏、关闭)应该通过这里的 API 来完成,而不是直接调用对话框。
Thus, you should not use getDialog().dismiss()
, since that would invoke dismiss()
on the dialog. Instead, you should use the dismiss()
method of the DialogFragment itself:
因此,您不应使用getDialog().dismiss()
,因为这会dismiss()
在对话框上调用。相反,您应该使用dismiss()
DialogFragment 本身的方法:
public void dismiss()
Dismiss the fragment and its dialog. If the fragment was added to the back stack, all back stack state up to and including this entry will be popped. Otherwise, a new transaction will be committed to remove the fragment.
公共无效解雇()
关闭片段及其对话框。如果片段被添加到后退堆栈,则直到并包括此条目的所有后退堆栈状态都将被弹出。否则,将提交一个新事务以删除该片段。
As you can see, this takes care not only of closing the dialog but also of handling the fragment transactions involved in the process.
如您所见,这不仅负责关闭对话框,还负责处理流程中涉及的片段事务。
You only need to use onStop
if you explicitly created any resources that require manual cleanup (closing files, closing cursors, etc.). Even then, I would override onStop
of the DialogFragment rather than onStop
of the underlying Dialog.
仅onStop
当您明确创建任何需要手动清理的资源(关闭文件、关闭游标等)时才需要使用。即便如此,我也会覆盖onStop
DialogFragment 而不是onStop
底层 Dialog。
回答by Terel
I think a better way to close a DialogFragment
is this:
我认为关闭 a 的更好方法DialogFragment
是:
Fragment prev = getSupportFragmentManager().findFragmentByTag("fragment_dialog");
if (prev != null) {
DialogFragment df = (DialogFragment) prev;
df.dismiss();
}
This way you dont have to hold a reference to the DialogFragment
and can close it from everywhere.
这样您就不必持有对 的引用,DialogFragment
并且可以从任何地方关闭它。
回答by Shiva Tiwari
Why don't you try using only this code:
为什么不尝试仅使用此代码:
dismiss();
If you want to dismiss the Dialog Fragment by its own. You can simply put this code inside the dialog fragment where you want to dismiss the Dialog.
如果您想自行关闭对话框片段。您可以简单地将此代码放在要关闭对话框的对话框片段中。
For example:
例如:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
This will close the recent Dialog Fragment that is shown on the screen.
这将关闭屏幕上显示的最近的对话框片段。
Hope it helps for you.
希望对你有帮助。
回答by JustinMorris
I gave an upvote to Terel's answer. I just wanted to post this for any Kotlin users:
我对特雷尔的回答表示赞同。我只是想为任何 Kotlin 用户发布这个:
supportFragmentManager.findFragmentByTag(TAG_DIALOG)?.let {
(it as DialogFragment).dismiss()
}
回答by Phil
Kotlin Versionof Terel answer
Kotlin 版本的 Terel 答案
(fragmentManager.findFragmentByTag(TAG) as? DialogFragment)?.dismiss()
回答by Venky
You should dismiss you Dialog
in onPause()
so override it.
你应该解雇你Dialog
,onPause()
所以覆盖它。
Also before dismissing you can check for null
and is showing like below snippet:
同样在解雇之前,您可以检查null
并显示如下片段:
@Override
protected void onPause() {
super.onPause();
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
}
回答by Maksim Ivanov
There are references to the official docs (DialogFragment Reference) in other answers, but no mention of the example given there:
在其他答案中有对官方文档(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");
}
This removes any currently shown dialog, creates a new DialogFragment with an argument, and shows it as a new state on the back stack. When the transaction is popped, the current DialogFragment and its Dialog will be destroyed, and the previous one (if any) re-shown. Note that in this case DialogFragment will take care of popping the transaction of the Dialog is dismissed separately from it.
这将删除任何当前显示的对话框,创建一个带有参数的新 DialogFragment,并将其显示为返回堆栈上的新状态。当事务弹出时,当前的 DialogFragment 及其 Dialog 将被销毁,并重新显示前一个(如果有)。请注意,在这种情况下,DialogFragment 将负责弹出 Dialog 的事务,并与它分开解散。
For my needs I changed it to:
根据我的需要,我将其更改为:
FragmentManager manager = getSupportFragmentManager();
Fragment prev = manager.findFragmentByTag(TAG);
if (prev != null) {
manager.beginTransaction().remove(prev).commit();
}
MyDialogFragment fragment = new MyDialogFragment();
fragment.show(manager, TAG);
回答by jon
I found that when my fragment was defined in the navigation graph with a <fragment>
tag (for a full screen dialogfragment), the dialogfragment would not dismiss with the dismiss()
command. Instead, I had to pop the back stack:
我发现当我的片段在导航图中用<fragment>
标签定义时(对于全屏对话框片段),对话框片段不会用dismiss()
命令关闭。相反,我不得不弹出返回堆栈:
findNavController(getActivity(), R.id.nav_host_fragment).popBackStack();
However, if the same dialogfragment was defined in the navigation graph with a <dialog>
tag, dismiss()
works fine.
但是,如果在导航图中使用<dialog>
标记定义了相同的对话框片段,则dismiss()
工作正常。
回答by Victor Odiah
CustomFragment dialog = (CustomDataFragment) getSupportFragmentManager().findFragmentByTag("Fragment_TAG");
if (dialog != null) {
dialog.dismiss();
}
回答by mikehc
Adding to the other answers, when having a DialogFragment
that is full screen calling dismiss()
won't pop the DialogFragment from the fragment backstack. A workaround is to call onBackPressed()
on the parent activity.
添加到其他答案中,当进行DialogFragment
全屏调用dismiss()
时,不会从片段后台堆栈中弹出 DialogFragment。一种解决方法是调用onBackPressed()
父活动。
Something like this:
像这样的东西:
CustomDialogFragment.kt
CustomDialogFragment.kt
closeButton.onClick {
requireActivity().onBackPressed()
}