OnCancelListener不叫在DialogFragment [英] OnCancelListener is not called in DialogFragment

查看:622
本文介绍了OnCancelListener不叫在DialogFragment的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 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。 该<一href="http://developer.android.com/reference/android/content/DialogInterface.OnCancelListener.html">OnCancelListener文件说:

  

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

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

无论是做出了积极/消极的按钮带有 OnClickListener 调用<一href="http://developer.android.com/reference/android/content/DialogInterface.html#cancel%28%29"><$c$c>DialogInterface#cancel()或者使用<一个href="http://developer.android.com/reference/android/content/DialogInterface.OnDismissListener.html"><$c$c>OnDismissListener()一个额外的检查,看是否有列表项被点击了。

另外,监听一个返回键preSS并取消该对话框,您可以建立一个<一个href="http://developer.android.com/reference/android/content/DialogInterface.OnKeyListener.html"><$c$c>OnKeyListener,像<一个概述href="http://stackoverflow.com/questions/7801971/android-how-to-override-onback$p$pssed-in-alertdialog/7815342#7815342">this SO回答

此外,一旦你的对话框中设置时,它也将使用<一个好主意href="http://developer.android.com/reference/android/app/Dialog.html#setCanceledOnTouchOutside%28boolean%29"><$c$c>Dialog#setCanceledOnTouchOutside()万一对话外的用户点击。

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

由于您使用的是 DialogFragment ,这个类有一个非常方便的方法,<一个href="http://developer.android.com/reference/android/app/DialogFragment.html#onCancel%28android.content.DialogInterface%29"><$c$c>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!

这篇关于OnCancelListener不叫在DialogFragment的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆