Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/187.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何正确地消除DialogFragment?_Android_Android Dialogfragment - Fatal编程技术网

Android 如何正确地消除DialogFragment?

Android 如何正确地消除DialogFragment?,android,android-dialogfragment,Android,Android Dialogfragment,文档对对话框中的dislose()方法说: 关闭此对话框,将其从屏幕上删除。可以调用此方法 从任何线程安全。请注意,您不应重写此方法来执行以下操作 清除对话框关闭时,请在onStop()中执行该操作 在我的代码中,我所做的就是调用getDialog().disease()来取消它。但我没有做任何其他事情,甚至没有使用onStop()。因此,我要问的是如何正确地关闭对话框片段,以避免任何内存泄漏等。您应该在onPause()中关闭对话框,以便覆盖它 同样,在解雇之前,您可以检查null,并显示如下

文档对
对话框中的
dislose()
方法说:

关闭此对话框,将其从屏幕上删除。可以调用此方法 从任何线程安全。请注意,您不应重写此方法来执行以下操作 清除对话框关闭时,请在
onStop()
中执行该操作


在我的代码中,我所做的就是调用
getDialog().disease()
来取消它。但我没有做任何其他事情,甚至没有使用
onStop()
。因此,我要问的是如何正确地关闭
对话框片段
,以避免任何内存泄漏等。

您应该在
onPause()
中关闭
对话框
,以便覆盖它

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

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

tl;dr:关闭对话框片段的正确方法是直接在对话框片段上使用
discouse()


详细信息:各州

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

因此,您不应该使用
getDialog().disease()
,因为这样会调用对话框上的
disease()
。相反,您应该使用DialogFragment本身的
dismise()
方法:

公开作废驳回()

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

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


如果您明确创建了任何需要手动清理的资源(关闭文件、关闭光标等),则只需使用
onStop
。即使如此,我还是会覆盖DialogFragment的
顶部
,而不是底层对话框的
顶部

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

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

这样,您就不必持有对
对话框片段的引用,并且可以从任何地方关闭它。

我对特雷尔的答案投了赞成票。我只是想为任何Kotlin用户发布以下内容:

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

Terel answer的Kotlin版本

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

为什么不尝试只使用以下代码:

dismiss();
如果您想自己关闭对话框片段。您可以简单地将此代码放在对话框片段中,您希望在其中关闭对话框

例如:

button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       dismiss();
   }
});
这将关闭屏幕上显示的最近的对话框片段

希望它能对您有所帮助。

只需从您要消除的片段中调用disclesh()

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

其他答案中提到了官方文件(),但没有提到其中给出的示例:

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将负责弹出事务 对话框的所有部分都将与它分开

出于我的需要,我将其更改为:

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

MyDialogFragment fragment = new MyDialogFragment();
fragment.show(manager, TAG);

我发现,当在导航图中使用
标记(对于全屏dialogfragment)定义我的片段时,dialogfragment不会使用
disease()
命令关闭。相反,我必须弹出后堆栈:

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

但是,如果在导航图中使用
标记定义了同一个dialogfragment,
Disease()
可以正常工作。

当使用全屏调用
Disease()
dialogfragment
添加到其他答案时,不会从片段backbackback弹出dialogfragment。解决方法是对父活动调用
onBackPressed()

CustomFragment dialog = (CustomDataFragment) getSupportFragmentManager().findFragmentByTag("Fragment_TAG");
if (dialog != null) {
  dialog.dismiss();
}
大概是这样的:

CustomDialogFragment.kt

closeButton.onClick {
    requireActivity().onBackPressed()
}

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

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扩展函数,它关闭打开的对话框片段:

fun AppCompatActivity.whenDialogOpenDismiss(
    tag: String
) {
    supportFragmentManager.findFragmentByTag(tag)?.let { 
        if(it is DialogFragment) it.dismiss() }
}
当然,你可以直接从任何活动中调用它。
如果您需要从片段调用它,只需对Fragment类做相同的扩展函数

,他已经写过,他正在做dismise()及其关于DialogFragment的操作。我认为这对Dialog和DialogFragments@PareshMayani都有效。我相信@PareshMayani是正确的Venky。谷歌的
DialogFragment
教程没有显示正在使用的
onPause()
方法。但我想我明白你在做什么了。如果用户没有调用onPause()
,那又有什么意义呢。这时系统知道片段正在被调用。什么时候,比如说用户取消了。在这种情况下,有什么更好的方法来关闭它?@ScootrNova:不应该,你可能在其他地方有一个bug。您是如何创建片段的?
protectedvoid showDialogFragment(final DialogFragment fragment){final FragmentTransaction fTransaction=getSupportFragmentManager().beginTransaction();fTransaction.addToBackStack(null);fragment.show(fTransaction,“dialog”);}
很抱歉出现了令人讨厌的一行!但你可能是对的,所以现在我写了另一个方法来结束我的对话。我使用dismise()方法解除它们的作用就是通过标记查找片段,如果片段不是null,则对其运行dismise()。哦,是的,在将片段传递给该方法之前,我正在对其进行
new
ing。@ScootrNova:嗯,没有发现任何错误——另一方面,我从未使用过兼容性库,所以我不能确定这一点。可能吧