Home » Android » How to make a listener for a datepickers cancel button in Android?

How to make a listener for a datepickers cancel button in Android?

Posted by: admin June 15, 2020 Leave a comment

Questions:

I’m using a datepicker in Android to let the user to choose the date. I want it to do one thing if the user picks a date and sets it (I have that working fine) and then to clear a certain text field if the user pushes the cancel button on the datepicker (open up the datepicker but then cancel out of it).

The way I’ve been trying is by making a

private DatePickerDialog.OnCancelListener mDateCancelListener =
    new DatePickerDialog.OnCancelListener() {
        public void onCancel(DialogInterface dialog) {
            timeClear(); //method that clears text field
        }

    };

then I do

TimePickerDialog timeDialog = new TimePickerDialog(this,
  mTimeSetListener,
  c.get(Calendar.HOUR),
  c.get(Calendar.MINUTE),
  false);
timeDialog.setOnCancelListener(mTimeCancelListener);

to attach the listener.

My problem is that the listener works if the user pushes the back button, but not if they push the cancel button. I tried using a dismiss listener, and that works, except for the fact that it goes off even whether I set or cancel the datepicker!

What do I need to do so something goes off if and only if I push the cancel button on my datepicker?

How to&Answers:

The only solution, counter intuitive, is that you need to “override” the cancel button:

    timeDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
            getString(R.string.cancel),
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    // do stuff
                }
            });

Answer:

You can create one boolean variable isDataSet and in dateSetListener perform isDataSet = true; and then attach onDismissListener with such a code:

if(isDataSet)
    //Data was set and neither back nor cancel button was clicked
else
    //back or cancel button was clicked

But don’t forget to set isDataSet = false each time you create a dialog.

Answer:

Okay after some experimentation I have found that what is needed is an OnDismissListener as shown below. Note that I developed my solution for a TimePickerDialog, but setOnDismissListener is inherited from Dialog so it should work the same for a DatePickerDialog.

timeDialog.setOnDismissListener(mOnDismissListener);


private DialogInterface.OnDismissListener mOnDismissListener =
    new DialogInterface.OnDismissListener() {
        public void onDismiss(DialogInterface dialog) {
            _logger.v("mOnDismissListener called");
            timeClear();
        }
    };

I have tested this and it works. In fact, I have found that the OnDismissListener is called in both of the scenarios that you mention, when the user clicks the Cancel button and when they hit the hardware back button. So you only need this one handler.

Lastly, now that I know what to google for, I found this article that describes the difference between an OnDismissListener and an OnCancelListener, in the section on “Using Dismiss Listeners”:

Answer:

This is the solution. It may helpful for someone else

 datePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            if (which == DialogInterface.BUTTON_NEGATIVE) {
                // do something
            }
        }
    });

Answer:

Try this:

timeDialog.getButton(TimePickerDialog.BUTTON_NEGATIVE).setOnClickListener(mTimeCancelListener);

(You’ll have to change mTimeCancelListener to implement DialogInterface.OnClickListener instead of OnCancelListener)

Answer:

The full solution (tested and working) is to combine the OnDismissListener (see Kenneth Baltrinic’s answer 3 above) together with the onDateSet boolean described by dilix (1 answer above). You need both because the onDismiss is used in all cases:
(1) user has selected actual data
(2) user has canceled
(3) user has hit hardware back button.

Using the combination enables you to differentiate between them.