在DialogFragment中处理按钮点击事件

11

我有一个继承自DialogFragment的片段,其中包含两个编辑框和两个按钮(确定和取消)的自定义布局。我的对话框使用onCreateView方法指定布局显示得很好,但我不知道如何处理按钮点击事件。在onCreateView方法中,button.setOnClickListener无法正常工作。这可能有一个简单的解决方案,但我已经卡了几个小时了。非常感谢您的建议或示例代码。

附言:我不想使用AlertDialog,因为在这种情况下,点击ok按钮时,对话框会自动关闭,我不能对edittext进行验证(例如:当用户按下ok按钮并且编辑框为空时,我不希望对话框消失)。这就是我选择创建自定义对话框并轻松管理按钮行为的原因。

6个回答

10
这是我正在使用的对话框代码(实际对话框GUI在布局资源 confirm_dialog.xml 中定义):
public class ConfirmDialog extends DialogFragment {

    public static String TAG = "Confirm Dialog";

    public interface ConfirmDialogCompliant {
        public void doOkConfirmClick();
        public void doCancelConfirmClick();
    }

    private ConfirmDialogCompliant caller;
    private String message;

    public ConfirmDialog(ConfirmDialogCompliant caller, String message){
        super();
        this.caller = caller;
        this.message = message;
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.confirm_dialog, container, false);
        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
        ((TextView) view.findViewById(R.id.textview_confirm)).setText(message);
        ((Button) view.findViewById(R.id.ok_confirm_button)).setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                // When button is clicked, call up to owning activity.
                caller.doOkConfirmClick();
            }
        });
        ((Button) view.findViewById(R.id.cancel_confirm_button)).setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                // When button is clicked, call up to owning activity.
                caller.doCancelConfirmClick();
            }
        });
        return view;
    }

}

对话框是使用以下行创建的

confirm_dialog = new ConfirmDialog(this, message);
confirm_dialog.show(getActivity().getSupportFragmentManager(), ConfirmDialog.TAG);

接口定义用于确保调用者(Fragment或Activity)实现了处理控制器抛出的事件的方法。也就是说,调用此对话框的Fragment或Activity必须实现给定的接口。
也许有更好的解决方案,但这是我想出来的一个。希望能有所帮助!


像这样设置onClickListener对我没有起作用。它给了我错误。我找到了解决方法,并将其作为评论写在第一个答案中。无论如何,感谢您的回复。 - Sandra
如果您从XML资源中膨胀布局,则此方法有效。如果您以编程方式创建布局,则需要在按钮引用上调用setOnClickListener方法。 - type-a1pha
是的,我也在onCreateView方法中从XML资源中加载一个布局。我的问题是:myButton.setOnClickListener(new OnClickListener() {} 给我报错,所以解决方案是使用 myButton.setOnClickListener(new View.OnClickListener() {}. 我不知道为什么它不能识别我的监听器,但它就是这样。 - Sandra
1
这是我想到的相同解决方案,但我犹豫以这种方式实现,因为Fragment应该具有默认构造函数。另外,我不知道如何将接口“Caller”放入Args Bundle中。有任何想法吗? - Guillaume Jobin
5
当您的片段重新实例化(例如在配置更改或后台被销毁后)并且您单击按钮时,这将导致NPE崩溃。当片段管理器重新创建片段时,将调用默认构造函数。 - Tom

8

以下是一个处理来自FragmentDialog类的对话框取消按钮点击的示例:

我使用了android.support.v4.app.DialogFragment;

public class MyDialogFragment extends DialogFragment { 
    public MyDialogFragment(){}     
    public static String TAG = "info Dialog";
    Button btn;   
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.info_layout, container);
        getDialog().requestWindowFeature(STYLE_NO_TITLE);
        btn=(Button)view.findViewById(R.id.close_dialog_btn_info_layout);
        btn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                getDialog().dismiss();
            }
        });

        return view;
    }





}

7
按照以下步骤操作
Dialog dl = mDialogFragment.getDialog();
Button btn = dl.findViewById(R.id.btn);
btn.setOnClickListener(this);

2
谢谢。我已经找到了这样的解决方案。buttonOk.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { } } });但也许你的解决方案也可以。无论如何,谢谢! - Sandra
3
getDialog() 返回 null! - Dr.jacky

6
另一种选择是让您的自定义DialogFragment类实现OnClickListener。然后,您只需为您想要处理点击事件的任何视图设置setOnClickListener并在onClick中捕获点击。
// 1. implement OnClickListener
public class MyDialogFragment extends DialogFragment implements View.OnClickListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        LayoutInflater inflater = getActivity().getLayoutInflater();
        View view = inflater.inflate(R.layout.my_dialog_layout, null);

        // 2. set click listeners on desired views 
        view.findViewById(R.id.my_view_1).setOnClickListener(this);
        view.findViewById(R.id.my_view_2).setOnClickListener(this);


        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setView(view)
                // ...
        return builder.create();
    }   

    // 3. capture the clicks and respond depending on which view
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.my_view_1:
                // do something
                break;
            case R.id.my_view_2:
                // do something
                break;
            default:
                break;
        }
    }
}

1

这在Activity中很容易实现,但在DialogFragment中需要编写更多代码。

在DialogFragment类中,在onActivityCreated方法中执行您的常规findView操作。

btn_ocak = (Button) view.findViewById(R.id.btn_cal_ocak);
    btn_subat = (Button) view.findViewById(R.id.btn_cal_subat);
    btn_mart = (Button) view.findViewById(R.id.btn_cal_mart);
    btn_nisan = (Button) view.findViewById(R.id.btn_cal_nisan);


 btn_ocak.setOnClickListener(this);
    btn_subat.setOnClickListener(this);
    btn_mart.setOnClickListener(this);
    btn_nisan.setOnClickListener(this);

在你的类中实现 onClick OnClickListener。
public class CalendarPopUp extends DialogFragment implements View.OnClickListener

在onClick方法中执行想要的操作,通过这些步骤,我们激活了视图的onClick事件。

   @Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.btn_cal_ocak:
            seciliAy = "Ocak";
            setMonthOnShare(seciliAy);
            mCallback.onSelectedData(seciliAy);
            dismiss();
            break;
        case R.id.btn_cal_subat:
            seciliAy = "Subat";
            setMonthOnShare(seciliAy);
            mCallback.onSelectedData(seciliAy);
            dismiss();
            break;
        case R.id.btn_cal_mart:
            seciliAy = "Mart";
            setMonthOnShare(seciliAy);
            mCallback.onSelectedData(seciliAy);
            dismiss();
            break;
        case R.id.btn_cal_nisan:
            seciliAy = "Nisan";
            setMonthOnShare(seciliAy);
            mCallback.onSelectedData(seciliAy);
            dismiss();
            break;
        case R.id.btn_cal_mayis:
            seciliAy = "Mayıs";
            setMonthOnShare(seciliAy);
            mCallback.onSelectedData(seciliAy);
            dismiss();
            break;
        case R.id.btn_cal_haziran:
            seciliAy = "Haziran";
            setMonthOnShare(seciliAy);
            mCallback.onSelectedData(seciliAy);
            dismiss();
            break;
        case R.id.btn_cal_temmuz:
            seciliAy = "Temmuz";
            setMonthOnShare(seciliAy);
            mCallback.onSelectedData(seciliAy);
            dismiss();
            break;
        case R.id.btn_cal_agustos:
            seciliAy = "Agustos";
            setMonthOnShare(seciliAy);
            mCallback.onSelectedData(seciliAy);
            dismiss();
            break;
        case R.id.btn_cal_eylul:
            seciliAy = "Eylül";
            setMonthOnShare(seciliAy);
            mCallback.onSelectedData(seciliAy);
            dismiss();
            break;
        case R.id.btn_cal_ekim:
            seciliAy = "Ekim";
            setMonthOnShare(seciliAy);
            mCallback.onSelectedData(seciliAy);
            dismiss();
            break;
        case R.id.btn_cal_kasim:
            seciliAy = "Kasım";
            setMonthOnShare(seciliAy);
            mCallback.onSelectedData(seciliAy);
            dismiss();
            break;
        case R.id.btn_cal_aralik:
            seciliAy = "Aralık";
            setMonthOnShare(seciliAy);
            mCallback.onSelectedData(seciliAy);
            dismiss();
            break;
        default:
            break;
    }
}

如果您想知道如何传递值,请按照以下步骤操作 点击此处


1

或者

class MyDialog extends DialogFragment {
   public View.OnClickListener onButtonOk;
   public EditText edit_text;

   @Override
   public Dialog onCreateDialog(Bundle savedInstanceState) {
       AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
       LayoutInflater li = LayoutInflater.from(builder.getContext());
       View view = li.inflate(R.layout.custom_dialog, null);
       Button buttonOK = view.findViewById(R.id.button_ok);
       edit_text = view.findViewById(R.id.edit_text);
       buttonOk.setOnClickListener(onButtonOk);
       builder.setView(view);

       return builder.create();
   }

}


// use
final MyDialog dialog=new MyDialog();
dialog.onButtonOk=new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(v.getContext(), dialog.edit_text.getText(), Toast.LENGTH_SHORT).show();
    }
};
dialog.show(getSupportFragmentManager(),null);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接