Android 片段中的自定义取消按钮';s警报对话框';s单击事件未处理

Android 片段中的自定义取消按钮';s警报对话框';s单击事件未处理,android,android-layout,android-fragments,onclicklistener,android-button,Android,Android Layout,Android Fragments,Onclicklistener,Android Button,我创建了一个对话框,它的布局、取消和提交按钮都是完全定制的,这要归功于一个布局。我想处理两个按钮的点击-特别是,我们在这个问题中考虑取消按钮。< /P> 问题 单击cancel按钮时,不会执行click事件处理程序 实施 解释 我创建了一个对话片段。在中,我使用dialogs builder创建我的对话框(按照官方文档的建议)。我为cancel按钮设置了click处理程序,并在中取消了对话框 可以单击“取消”按钮(如布局文件中所指定)。因此,该事件通常被很好地触发。这似乎是无法处理的 来源 Di

我创建了一个对话框,它的布局、取消和提交按钮都是完全定制的,这要归功于一个布局。我想处理两个按钮的点击-特别是,我们在这个问题中考虑取消按钮。< /P> 问题 单击cancel按钮时,不会执行click事件处理程序

实施 解释 我创建了一个对话片段。在中,我使用dialogs builder创建我的对话框(按照官方文档的建议)。我为cancel按钮设置了click处理程序,并在中取消了对话框

可以单击“取消”按钮(如布局文件中所指定)。因此,该事件通常被很好地触发。这似乎是无法处理的

来源 DialogFragment.java 注意:在下面的示例中,没有显示输出“ok”,而显示按钮参考的输出是。这意味着设置单击事件处理程序的函数已执行(并且按钮已从布局中正确获取),但单击事件处理程序甚至在执行单击时也未执行

    public class DialogFragment extends DialogFragment {

        @NonNull
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            // Use the Builder class for convenient dialog construction
            AlertDialog.Builder builder = new AlertDialog.Builder(Objects.requireNonNull(getActivity()));
            builder.setView(R.layout.dialog);
            View view = LayoutInflater.from(this.getContext()).inflate(R.layout.dialog, null);
            Dialog dialog = builder.create();
            setCancelButtonListener((Button) Objects.requireNonNull(view.findViewById(R.id.button_cancel)), dialog);
            return dialog;
        }
    private void setCancelButtonListener(Button button, final Dialog dialog) {
        System.out.println(button);
        button.setOnClickListener( new Button.OnClickListener() {

            @Override
            public void onClick(View v) {
                System.out.println("ok");
                dialog.cancel();
            }
        });
    }

}
dialog.xml(即:片段的xml布局中的取消按钮)

问题:
为什么不处理按钮单击事件?如何使其工作?

看看代码中的这两行:

builder.setView(R.layout.dialog);
View view = LayoutInflater.from(this.getContext()).inflate(R.layout.dialog, null);
在这里,您将布局的资源id提供给
AlertDialog.Builder
,以便它使用它填充
AlertDialog
的“可自定义”区域。(您可以通过首先膨胀
视图
,然后调用
AlertDialog.Builder.setView(视图)
来实现相同的效果)

接下来,通过再次膨胀相同的布局文件,让
LayoutInflater
创建一个
视图
。这个新的
视图
可以通过
onCreateDialog()
中的局部变量视图访问,但它从未添加到任何
视图组
,因此它将永远不会实际显示。由于无法单击此
视图中包含的
按钮
,因此其
OnClickListener
将永远不会启动

因此,您应该如下设置
警报对话框

AlertDialog.Builder builder = new AlertDialog.Builder(Objects.requireNonNull(getActivity()));
View view = LayoutInflater.from(this.getContext()).inflate(R.layout.dialog, null);
builder.setView(view);
Dialog dialog = builder.create();
setCancelButtonListener((Button) Objects.requireNonNull(view.findViewById(R.id.button_cancel)), dialog);
return dialog;

充气后使用builder.setView(view)(LayoutInflater.from…)我几个小时以来一直在处理这个问题,甚至没有意识到这个非常愚蠢的错误。。。!谢谢你的帮助!是否可以使用
builder.setView(R.layout.dialog)
并调用一种
builder.getView
,避免使用充气机?@JarsOfJam调度程序-对于
AlertDialog.builder
,似乎没有
getView()
。但是您可以通过使用dialog.getWindow().getDecorView().findViewById(R.id.Button\u cancel)
dialog.getWindow().getDecorView().findViewById(R.id.Button\u cancel)
来获取
按钮。很遗憾,findViewById(R.id.Button\u cancel)
返回空值(decor视图存在,但找不到按钮,因此
findViewById
返回空值)@JarsOfJam调度程序-然后可能会帮助您。请注意,某些方法的行为甚至似乎取决于设备。依我看,首先膨胀布局,然后从结果视图中获取按钮比任何其他方法都简单可靠。
AlertDialog.Builder builder = new AlertDialog.Builder(Objects.requireNonNull(getActivity()));
View view = LayoutInflater.from(this.getContext()).inflate(R.layout.dialog, null);
builder.setView(view);
Dialog dialog = builder.create();
setCancelButtonListener((Button) Objects.requireNonNull(view.findViewById(R.id.button_cancel)), dialog);
return dialog;