11

I have Fragment that extends DialogFragment and I have a custom layout for it which contains two edittexts and two buttons - ok and cancel. My dialog displays just fine, using the onCreateView method for specifying the layout, but I don't know how to handle button clicks. Inside the onCreateView method, button.setOnClickListener doesn't work. This may have a simple solution, but I am stuck for several hours. I would very much appreciate an advice or example code.

P.S I don't want to use AlertDialog, because in this case when clicking on the ok button, the dialog automatically dismisses itself, and I can't do a validation on the edittext's (example: when the user presses ok button and the edittext's are empty I don't want the dialog to disappear). That is way I went with the option for creating a custom dialog and easily manage the buttons behavior.

Sandra
  • 4,239
  • 10
  • 47
  • 80

6 Answers6

10

This is the code for a Dialog I'm using (the actual GUI for the dialog is defined in the layout resource 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;
    }

}

The dialog is created with the following lines

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

The interface definition is used to assure that the caller (Fragment or Activity) implements the methods to handle the events thrown by the controller. That is, a Fragment or Activity calling this dialog must implement the given interface.
Maybe there is a better solution but this is the one I figured out. Hope it helps!

type-a1pha
  • 1,891
  • 13
  • 19
  • setting the onClickListener like this didn't work for me. It gave me errors. I found a solution to my problem, and wrote it as a comment to the first answer. Thank you for your response anyway. – Sandra Aug 24 '12 at 15:32
  • This works if you're inflating your layout from an xml resource. If you're creating your layout programmatically then you got ta call setOnClickListener on your Button reference. – type-a1pha Aug 25 '12 at 13:06
  • Yes, I also inflate a layout from an xml resource in the onCreateView method. The problem I was having was that: myButton.setOnClickListener(new OnClickListener() {} was giving me error, so the solution was using myButton.setOnClickListener(new View.OnClickListener() {}. I don't know why it did not recognize my listener that way, but it did.. – Sandra Aug 27 '12 at 07:14
  • 1
    This is the same solution I tought of, but I hesistate to make it this way because Fragment should have default constructors. In addition, I don't know how to put the Interface "Caller" in a Args Bundle. Any Idea ? – Guillaume Jobin Jan 31 '14 at 20:54
  • 5
    This will crash with a NPE after your fragment is re-instantiated (after a config change or being destroyed in the background for eg) and you click on a button. The default constructor is called when the fragment manager re-creates a fragment. – Tom Mar 31 '15 at 02:50
8

here is an example to handel a cancel button click on a dialog from the FragmentDialog class:

i used 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;
    }





}
Gal Rom
  • 6,221
  • 3
  • 41
  • 33
7

Do along these lines

Dialog dl = mDialogFragment.getDialog();
Button btn = dl.findViewById(R.id.btn);
btn.setOnClickListener(this);
Khronos
  • 377
  • 6
  • 17
nandeesh
  • 24,740
  • 6
  • 69
  • 79
  • 2
    Thank u. I already found a solution like this. buttonOk.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { } } }); but maybe your solution works too. Thx anyway! – Sandra Aug 24 '12 at 15:28
  • 3
    `getDialog()` returns null! – Dr.jacky Apr 23 '18 at 10:02
6

Another option is to let your custom DialogFragment class implement OnClickListener. Then you just setOnClickListener for whatever views you want to handle clicks on and catch the clicks in 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;
        }
    }
}
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
1

Its easy in activity but in DialogFragment we do some more codes.

Inside the DialogFragment class do your rutin findView on onActivityCreatedmethod

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

Implement onClick OnClickListener to your class

public class CalendarPopUp extends DialogFragment implements View.OnClickListener

and do what you want inside onClick method, by doing these we activated the onClick events of our views

   @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;
    }
}

and if you wonder how to pass values follow these step clike_here

Samir
  • 6,405
  • 5
  • 39
  • 42
1

or

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);
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Peter
  • 329
  • 7
  • 9