【问题标题】:handle button clicks in a DialogFragment处理 DialogFragment 中的按钮点击
【发布时间】:2012-08-20 04:11:59
【问题描述】:

我有扩展 DialogFragment 的片段,并且我有一个自定义布局,其中包含两个编辑文本和两个按钮 - 确定并取消。我的对话框显示得很好,使用 onCreateView 方法指定布局,但我不知道如何处理按钮点击。在 onCreateView 方法中,button.setOnClickListener 不起作用。这可能有一个简单的解决方案,但我被困了几个小时。非常感谢您的建议或示例代码。

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

【问题讨论】:

    标签: android buttonclick android-dialogfragment


    【解决方案1】:

    这是我正在使用的对话框的代码(对话框的实际 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 对我不起作用。它给了我错误。我找到了解决问题的方法,并将其写为对第一个答案的评论。无论如何,感谢您的回复。
    • 如果您从 xml 资源中扩展您的布局,则此方法有效。如果您以编程方式创建布局,那么您可以在 Button 引用上调用 setOnClickListener。
    • 是的,我还在 onCreateView 方法中从 xml 资源扩展布局。我遇到的问题是:myButton.setOnClickListener(new OnClickListener() {} 给了我错误,所以解决方案是使用 myButton.setOnClickListener(new View.OnClickListener() {}。我不知道为什么它没有以这种方式认出我的听众,但确实如此..
    • 这是我坚持的解决方案,但我犹豫要不要这样做,因为 Fragment 应该有默认的构造函数。另外,我不知道如何将接口“调用者”放在 Args Bundle 中。有什么想法吗?
    • 在您的片段被重新实例化后(例如在配置更改或在后台被销毁后)并且您单击一个按钮后,这将与 NPE 一起崩溃。当片段管理器重新创建片段时,会调用默认构造函数。
    【解决方案2】:

    这里有一个例子来处理从 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;
        }
    
    
    
    
    
    }
    

    【讨论】:

      【解决方案3】:

      按照这些思路去做

      Dialog dl = mDialogFragment.getDialog();
      Button btn = dl.findViewById(R.id.btn);
      btn.setOnClickListener(this);
      

      【讨论】:

      • 谢谢你。我已经找到了这样的解决方案。 buttonOk.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { } } });但也许你的解决方案也有效。无论如何谢谢!
      • getDialog() 返回 null!
      【解决方案4】:

      另一种选择是让您的自定义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;
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        它在活动中很容易,但在 DialogFragment 中我们会编写更多代码。

        在 DialogFragment 类中,在 onActivityCreatedmethod 上执行你的 rutin 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;
            }
        }
        

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

        【讨论】:

          【解决方案6】:

          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);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-01-24
            相关资源
            最近更新 更多