OnCancelListener不叫在DialogFragment不叫、OnCancelListener、DialogFragment

2023-09-06 13:18:48 作者:深情不改必坠深海

我有一个简单的 AlertDialog 显示了一些项目,并在点击其中的一个,点击的项目被传递回封闭列表活动。我也想进行一些默认的处理,当用户取消对话框(使用的后退按钮的) - 更确切地说,我想传递一个空字符串在这种情​​况下,活性

不过,如果我把对话在 DialogFragment (从兼容包),在 OnCancelListener 是不是当我关闭对话框的后退按钮调用。我究竟做错了什么?

 公共类SelectItemDialog扩展DialogFragment {

    公共接口回调{
        无效onItemSelected(字符串字符串);
    }

    私有静态最后弦乐ARG_ITEMS =项目;

    私人回调回调;

    公共静态SelectItemDialog fromItems(集<字符串>项目){
        SelectItemDialog片段=新SelectItemDialog();
        fragment.setArguments(newArguments(项目));
        返回片段;
    }

    私有静态捆绑newArguments(集<字符串>项目){
        捆绑参数=新包();
        arguments.putStringArray(ARG_ITEMS,items.toArray(新的String [items.size()));
        返回的参数;
    }

    @覆盖
    公共无效onAttach(活动活动){
        super.onAttach(活动);
        回调=(回调)的活动;
    }

    @覆盖
    公共对话onCreateDialog(包savedInstanceState){
        。最终的String []项目= getArguments()getStringArray(ARG_ITEMS);
        返回新AlertDialog.Builder(getActivity())
            .setTitle(R.string.dialog_select_email_title)
            .setItems(项目,新OnClickListener(){
                @覆盖
                公共无效的onClick(DialogInterface对话,诠释它){
                    callback.onItemSelected(项目[它]);
                }
            })
            .setOnCancelListener(新OnCancelListener(){
                @覆盖
                公共无效OnCancel的(DialogInterface对话){
                    //不执行此code为
                    callback.onItemSelected();
                    抛出新的RuntimeException(对话框中取消);
                }
            })
            。创建();
    }
}
 

解决方案

它可能有做的事实,那就是从没有显式调用取消()您code。 该OnCancelListener文件说:

  

这将只能被称为对话框被取消时,

这可能需要一个明确的取消()通话。

无论是做出了积极/消极的按钮带有 OnClickListener 调用DialogInterface#cancel()或者使用OnDismissListener()一个额外的检查,看是否有列表项被点击了。

另外,监听一个返回键preSS并取消该对话框,您可以建立一个OnKeyListener,像this SO回答

此外,一旦你的对话框中设置时,它也将使用Dialog#setCanceledOnTouchOutside()万一对话外的用户点击。

编辑:以下部分是最简单的方法来处理在DialogFragment取消事件

由于您使用的是 DialogFragment ,这个类有一个非常方便的方法,DialogFragment#onCancel()它被调用时, DialogFragment 将被取消。难道你的逻辑在那里。

DialogFragments比较复杂,略有不同的生命周期比正常的对话。因此,首先要检查的文件,如果你有,你正试图移植到一个特定对话框为基础的方法 DialogFragment ,有些方法可能存在,让你的新的实现正常!

天佑见面叫龙哥,源佑手捆一起白扯,赵本六靠卖号活着

I have a simple AlertDialog that displays a list of some items and upon clicking one of them, the clicked item is passed back to the enclosing Activity. I also want to perform some default handling when the user cancels the dialog (using the back button) - more specifically, I want to pass an empty string to the activity in such case.

However, if I put the dialog in a DialogFragment (from the compatibility package), the OnCancelListener is not called when I close the dialog with the back button. What am I doing wrong?

public class SelectItemDialog extends DialogFragment {

    public interface Callback {
        void onItemSelected(String string);
    }

    private static final String ARG_ITEMS = "items";

    private Callback callback;

    public static SelectItemDialog fromItems(Collection<String> items) {
        SelectItemDialog fragment = new SelectItemDialog();
        fragment.setArguments(newArguments(items));
        return fragment;
    }

    private static Bundle newArguments(Collection<String> items) {
        Bundle arguments = new Bundle();
        arguments.putStringArray(ARG_ITEMS, items.toArray(new String[items.size()]));
        return arguments;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        callback = (Callback) activity;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final String[] items = getArguments().getStringArray(ARG_ITEMS);
        return new AlertDialog.Builder(getActivity())
            .setTitle(R.string.dialog_select_email_title)
            .setItems(items, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    callback.onItemSelected(items[which]);
                }
            })
            .setOnCancelListener(new OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    // this code is not executed
                    callback.onItemSelected("");
                    throw new RuntimeException("dialog cancelled");
                }
            })
            .create();
    }
}

解决方案

It might have to do with the fact that there is no explicit call to cancel() from your code. The OnCancelListener documentation says:

This will only be called when the dialog is canceled

Which probably needs an explicit cancel() call.

Either make a positive/negative button with a OnClickListener that calls DialogInterface#cancel() or use a OnDismissListener() with an extra check to see if a list item was clicked.

Also, to listen for a back keypress and cancel the dialog, you can set up an OnKeyListener, like outlined in this SO answer

Also, once you have the Dialog set up, it would also be a good idea to use Dialog#setCanceledOnTouchOutside() in case the the user taps outside the Dialog.

Edit: The below part is the easy way to handle cancel events in a DialogFragment.

Since you are using a DialogFragment, this class has a very handy method, DialogFragment#onCancel() which gets called when the DialogFragment is cancelled. Do your logic in there.

DialogFragments are more complex, with a slightly different lifecycle than normal dialogs. Therefore, first check the documentation if you have a certain Dialog-based approach that you are trying to port to a DialogFragment, some methods may exist that allow your new implementation to function properly!