Android DialogFragment 被解除时的回调

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24151891/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:50:16  来源:igfitidea点击:

Callback When DialogFragment is Dismissed

androiddialog

提问by Impatient Dev

I want to launch a dialog with a custom layout, which I've implemented via a DialogFragment. (I basically just changed onCreateView() and added button handlers). The dialog lets the user quickly change an important setting.

我想启动一个带有自定义布局的对话框,这是我通过 DialogFragment 实现的。(我基本上只是更改了 onCreateView() 并添加了按钮处理程序)。该对话框允许用户快速更改重要设置。

This dialog will be launched from several different activities. The different activities don't have much in common, except that they need to refresh after the user makes a change to the setting. They don't need to get any information from the dialog; they merely need to know when it's closed (dismissed).

此对话框将从几个不同的活动中启动。不同的活动没有太多共同点,只是在用户更改设置后需要刷新。他们不需要从对话框中获取任何信息;他们只需要知道它何时关闭(关闭)。

What I've Tried

我试过的

I tried having the activity refresh in onResume(), but launching and dismissing a dialog never seems to call this method. (So I'm not sure why it even exists, but that's probably a topic for another question.)

我尝试在 onResume() 中刷新活动,但启动和关闭对话框似乎从未调用此方法。(所以我不确定它为什么存在,但这可能是另一个问题的主题。)

Next, I tried adding a DialogInterface.OnDismissListener to the dialog:

接下来,我尝试将 DialogInterface.OnDismissListener 添加到对话框中:

public static void showMyDialog(OnDismissListener listener, Activity activity)
{
    DialogFragment fragment = new MyDialogFragment();
    fragment.show(activity.getFragmentManager(), "date");
    activity.getFragmentManager().executePendingTransactions();//A
    fragment.getDialog().setOnDismissListener(listener);//B
}

When I originally left out the line A, I got a NullPointerException on line B because the dialog is null at that point. Following the advice of this SO answer, I put in the call to executePendingTransaction(). This causes an IllegalStateException on line B, with the message "OnDismissListener is already taken by DialogFragment and cannot be replaced." I also tried putting setOnDismissListener() before the call to show(), but that always caused a NullPointerException.

当我最初省略 A 行时,我在 B 行得到了 NullPointerException,因为此时对话框为空。按照这个 SO answer的建议,我调用了 executePendingTransaction()。这会导致 B 行出现 IllegalStateException,并显示消息“OnDismissListener 已被 DialogFragment 占用,无法替换”。我还尝试在调用 show() 之前放置 setOnDismissListener(),但这总是导致 NullPointerException。

I then read this other SO answer, which says the original asker was "calling getDialog() too early in the DialogFragment's life cycle." So I tried adding a constructor to my DialogFragment:

然后我阅读了另一个 SO answer,它说原始提问者“在 DialogFragment 的生命周期中过早地调用 getDialog()”。所以我尝试向我的 DialogFragment 添加一个构造函数:

public MyDialogFragment(SomeCallback illTakeAnythingICanGet)
{
    //I'll store the callback here and call it later
}

Unfortunately, adding a constructor made Android Lint freak out with a fatal warning, and when I looked it up, I found a comment in this questionthat seems to say this approach will make it impossible to deal with the user rotating the screen while the dialog is open.

不幸的是,添加一个构造函数让 Android Lint 发出致命警告,当我查看它时,我在这个问题中发现了一条评论,似乎说这种方法将无法处理用户在对话框中旋转屏幕开了。

The Question

问题

How can an activity figure out when a DialogFragment has closed (been dismissed) in a way that won't break my app if the user rotates the screen? Should I be using something else besides a DialogFragment?

如果用户旋转屏幕,活动如何以不会破坏我的应用程序的方式确定 DialogFragment 何时关闭(被关闭)?除了 DialogFragment 之外,我还应该使用其他东西吗?

回答by Impatient Dev

This is just a longer explanation of harism's comment in case anyone else has the same problem I did.

这只是对 harism 评论的更长解释,以防其他人遇到同样的问题。

You can accomplish what I wanted by creating an interface like this:

您可以通过创建这样的界面来完成我想要的:

public interface MyDialogCloseListener
{
    public void handleDialogClose(DialogInterface dialog);//or whatever args you want
}

Have the activity that launches your dialog (DialogFragment) implement this interface. Then give that DialogFragment the following method:

让启动对话框的活动 (DialogFragment) 实现此接口。然后为该 DialogFragment 提供以下方法:

public void onDismiss(DialogInterface dialog)
{
    Activity activity = getActivity();
    if(activity instanceof MyDialogCloseListener)
        ((MyDialogCloseListener)activity).handleDialogClose(dialog);
}

回答by shaby

More explanatory code for someone to do the same.

更多解释性代码供某人做同样的事情。

Create the interfaceas:

创建interface为:

package com.example.dialoglistener;
import android.content.DialogInterface;

public interface MyDialogCloseListener {
    public void handleDialogClose(DialogInterface dialog);
}

Implement the interface in activity as:

在活动中实现接口为:

MyDialogCloseListener closeListener = new MyDialogCloseListener() {
        @Override
        public void handleDialogClose(DialogInterface dialog) {                                     
            //do here whatever you want to do on Dialog dismiss
        }
};

Write a DismissListenerin DialogFragementas

DismissListenerDialogFragement

public void DismissListener(MyDialogCloseListener closeListener) {
        this.closeListener = closeListener;
}

call DismissListenerfrom your activity as:

DismissListener从您的活动中调用为:

dialogFragementObject.DismissListener(closeListener);

and finally write onDismissmethod

最后写onDismiss方法

@Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        if(closeListener != null) {
            closeListener.handleDialogClose(null);
        }

    }

回答by user3199522

Tyler's example was the only example I could find that actually worked. The only thing that needs changed for the example to work is the call to the DismissListner method in the DialogFragment class. He has it as:

Tyler 的例子是我能找到的唯一有效的例子。为了使示例工作,唯一需要更改的是对 DialogFragment 类中的 DismissListner 方法的调用。他把它作为:

dialogFragementObject.DismissListner(closeListener);

This just needs to be a cast to whatever your class name of that DialogFragment is. For example:

这只需要转换为该 DialogFragment 的任何类名。例如:

((MyDialogFragment)dialogFragementObject).DismissListner(closeListener);