在Android中创建自定义对话框的类外侦听器

在Android中创建自定义对话框的类外侦听器,android,android-fragments,android-dialog,android-dialogfragment,Android,Android Fragments,Android Dialog,Android Dialogfragment,我试图创建customdialog按钮的侦听器,该按钮扩展了DialogFragment类,我想在customdialog fragment类之外找到自定义按钮的侦听器。但是,当我试图调用customdialog fragment视图时,我得到了null异常。我要做的是在其他地方创建customdialog片段的新实例,并说 customdialog.getView().findViewById(R.id.custombutton) 但是我正在变空 public class CustomDial

我试图创建customdialog按钮的侦听器,该按钮扩展了DialogFragment类,我想在customdialog fragment类之外找到自定义按钮的侦听器。但是,当我试图调用customdialog fragment视图时,我得到了null异常。我要做的是在其他地方创建customdialog片段的新实例,并说

customdialog.getView().findViewById(R.id.custombutton)

但是我正在变空

public class CustomDialog extends DialogFragment {

public  final int RES_NONE = -1;
private  TextViewCustomFont dialogTitle, view2, dialogBodyBottom,
        dialogBodyTop;
private  EditTextCustomFont dialogEditText;
private  ButtonCustomFont dialogLeftButton;
private ButtonCustomFont dialogRightButton;
private  Typeface GothamBold, GothamMedium, GothamUltra;
private static  int title1, bodyTop1, bodyBottom1, EditTextHint1,
        leftButton1, rightButton1;
onSubmitListener mListener;

private  Dialog dialog;

interface onSubmitListener {
    void setOnSubmitListener(String arg);
}

public static CustomDialog newInstance(int title, int bodyTop,
        int bodyBottom, int EditTextHint, int leftButton, int rightButton) {

    title1 = title;
    bodyTop1 = bodyTop;
    bodyBottom1 = bodyBottom;
    EditTextHint1 = EditTextHint;
    leftButton1 = leftButton;
    rightButton1 = rightButton;

    CustomDialog frag = new CustomDialog();



    return frag;
}

public ButtonCustomFont getDialogLeftButton() {
    return dialogLeftButton;
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    dialog = new Dialog(getActivity());
    dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    //dialog.setContentView(R.layout.dialog_layout);
    //dialog.show();

    initLayout();

    return dialog;
}

private void initLayout(){
    dialog.setContentView(R.layout.dialog_layout);
    setDialogView();
    setCustomDialog();
}

public void setDialogView(){    

    //Create an java object of each dialog view item
    dialogTitle = (TextViewCustomFont) dialog.findViewById(R.id.custom_dialog_title);
    dialogBodyTop = (TextViewCustomFont) dialog.findViewById(R.id.custom_dialog_body_top);
    dialogBodyBottom = (TextViewCustomFont) dialog.findViewById(R.id.custom_dialog_body_bottom);
    dialogEditText = (EditTextCustomFont) dialog.findViewById(R.id.custom_dialog_body_et);
    dialogLeftButton = (ButtonCustomFont) dialog.findViewById(R.id.custom_dialog_body_btn_left);
    dialogRightButton = (ButtonCustomFont)  }

我正试图拉动CustomDialog片段的dialogLeftButton,并在LoginSessionFragment中分配一个侦听器

下面是我添加方法2后的情况。这是逻辑片段的一部分

private void TwoButtonTextEditTextDialog(){
    String title = getResources().getString(R.string.invalid_info_header);
    String body = getResources().getString(R.string.invalid_info_body);
    String body2 = getResources().getString(R.string.hint_newemail);
    String btn1 = getResources().getString(R.string.cancel_uppercase);
    String btn2 = getResources().getString(R.string.ok_alert);

    fragmentDialog = CustomDialog.newInstance(title, body, body2, RES_NONE, btn1, btn2);
    fragmentDialog.setCustomDialogFragmentListener(mDialogClickListener);
    fragmentDialog.show(getFragmentManager(), "");
}

private  CustomDialog.CustomDialogFragmentListener mDialogClickListener = new CustomDialog.CustomDialogFragmentListener(){ 

    @Override
    public void onNegativeClick() {
    // TODO Auto-generated method stub
    fragmentDialog.dismiss();
    }

    @Override
    public void onPositiveClick() {
    // TODO Auto-generated method stub
    fragmentDialog.dismiss();
    }

};


@Override
public void onNegativeClick() {
    // TODO Auto-generated method stub

}

@Override
public void onPositiveClick() {
    // TODO Auto-generated method stub

}
尝试使用此选项(未测试此选项) 公共类MyDialogFragment扩展了DialogFragment{

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setMessage(R.string.input_warning)
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.dismiss();
                }
            });

    return builder.create();
    }
}
在您的活动片段中

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle       savedInstanceState) {

    View view = inflater.inflate(R.layout.workout_a_fragment, container, false);

    Button button = (Button)view.findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        FragmentManager fm = getActivity().getFragmentManager();
        MyDialogFragment dialog = new MyDialogFragment();
        dialog.show(fm, DIALOG_WARNING);
    }

})}

您可以创建一个方法作为
setDialogButtonClickListener(CustomDialog.OnButtonClickListener clickListener)
where
CustomDialog.OnButtonClickListener
是一个内部静态界面,这样您就可以从任何地方收听按钮的单击事件

这方面的一个例子如下所示

   public class CustomDialog extends DialogFragment {

       .....
     public static CustomDialog newInstance(int title, int bodyTop,
        int bodyBottom, int EditTextHint, int leftButton, int rightButton) {

        CustomDialog frag = new CustomDialog();
        Bundle args = new Bundle();
        args.putInt("title", title);
        ......
        frag.setArguments(args);
        return frag;
    }

...
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        int title = getArguments().getInt("title");

        return new AlertDialog.Builder(getActivity())
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setTitle(title)
                .setPositiveButton(android.R.string.ok, this)
                .setNegativeButton(android.R.string.cancel, this)
                 ....
                .create();
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (listener != null) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                listener.onRightButtonClick();
            default:
                listener.onLeftButtonClick();
            }
        }
    }

    ...
    private CustomDialog.OnButtonClickListener mClickListener;
    ....

    public void setDialogButtonClickListener(CustomDialog.OnButtonClickListener clickListener){
         mClickListener = clickListener;
    }

    ...
    public static interface OnButtonClickListener {
       public void onLeftButtonClick();
       public void onRightButtonClick();
    }
    }
如果您注意到我发布的上述示例,我除了解决了您在按钮上设置单击侦听器的问题外,还向您介绍了Android上的工厂设计模式,您可以看到,我没有为按钮标题和对话框标题创建
静态
字段,而是在Bundle参数中设置它们,然后在Dialogs onCreate()方法中检索它们

有关Fragment的更多最佳实践,您可以查看

编辑

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle       savedInstanceState) {

    View view = inflater.inflate(R.layout.workout_a_fragment, container, false);

    Button button = (Button)view.findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        FragmentManager fm = getActivity().getFragmentManager();
        MyDialogFragment dialog = new MyDialogFragment();
        dialog.show(fm, DIALOG_WARNING);
    }
好的,为了您的帮助,我为您提供了一个LoginSectionFragment的大致外观

public class LoginSelectionFragment extends Fragment implements CustomDialog.OnButtonClickListener {

    ......// Method 1
    public void showDialog(String title , String message .....) {
         CustomDialog dialog = CustomDialog.getInstance(title , message...);
         dialog.setDialogButtonClickListener(this);
         dialog.show(getSupportFragmentManager(), null);
    }

        public void onLeftButtonClick(){
    ...// do something on left button click of dialog
    }
               public void onRightButtonClick(){
    // do something on right button click of dialog
    ..
    }

    // Method 2
public void showDialog2(String title , String message .....) {
         CustomDialog dialog = CustomDialog.getInstance(title , message...);
         dialog.setDialogButtonClickListener(mDialogClickListener);
         dialog.show(getSupportFragmentManager(), null);
}

private final CustomDialog.OnButtonClickListener mDialogClickListener = new CustomDialog.OnButtonClickListener() {
  public void onLeftButtonClick(){
        ...// do something on left button click of dialog
        }
                   public void onRightButtonClick(){
        // do something on right button click of dialog
        ..
        }
}
    }
现在,如果您查看方法1,我们为showDialog()方法提供了参数,这样您就可以重用它,以使用不同的参数多次显示,也就是说,当您想要显示具有不同标题、消息等的同一对话框时,可以使用这种方法

方法2中,我们提供了一个匿名内部类,用于处理单击事件。在相同的活动/片段中,您可以使用不同种类的对话框(即具有不同UI和不同事件侦听器的对话框)创建尽可能多的匿名内部类


享受吧

请添加您的代码,以便我们可以帮助您解决此问题。不,这一个不起作用,因为您用来拉按钮的视图属于Activty Fragment,但我想在另一个片段中拉Dialogfragmet的按钮谢谢您提供了这个很棒的短语,但我无法在另一个片段中拉这个customdialog片段的按钮碎片。这是我唯一要找的。始终获取nullleftBtn.setOnClickListener((android.view.view.OnClickListener)getActivity().getApplicationContext())。。或者这个:leftBtn.setOnClickListener((android.view.view.OnClickListener)this);我得到这个错误:。。。无法强制转换为android.view.view$onClickListener@user3152367我编辑了我的答案以供您的帮助,在我的答案中,我还详细说明了应该通过一个接口来收听外部类(或片段或活动)中DialogFragment内按钮的点击事件,这是一种称为“松耦合”的良好实践,您不应该从片段中拉出任何视图并在其上设置一个单击侦听器,因为通过拉出一个视图,您会创建一个“紧密耦合”,这是一个不好的对话框,请参阅我关于如何实现该对话框的答案,希望这会对您有所帮助,干杯!再次感谢你。根据你第一次给我的,我昨天就这么做了。但我今天在想,如果我在同一个片段上有多个对话呢?我将如何管理左键和右键侦听器。我可以根据button的字符串调用查询,但我试图避开基于字符串为结构创建查询。这是我的实时项目。将来我可能会在一个片段上有多个对话框。@user3152367我已经更新了我的答案,请看一看。我认为你想要有不同的对话框和不同的用户界面,然后你可以使用方法2,否则,如果你想用不同的标题显示当前的对话框等,请使用方法1。此外,如果您喜欢答案,请接受它或向上投票(这是对堆栈溢出表示感谢的最佳方式;))。干杯