How to get OnClick in DatePickerDialog.OnDateSetListener?

16,956

Solution 1

Date Picker Dialog you are using is deprecated so I recommend you to don't use that.

You can implement the Date picker in two ways(that I know of)

  1. Using DialogFragment
  2. Using AlertDialog

Using DialogFragment:

public class MainActivity extends FragmentActivity {
    EditText text;
    Button b;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        b=(Button)findViewById(R.id.button1);
        text=(EditText)findViewById(R.id.editText1);
        b.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                DateDialogFragment datepicker=new DateDialogFragment();
                datepicker.show(getSupportFragmentManager(), "showDate");
            }
        });
    }

    public class DateDialogFragment extends DialogFragment  implements DatePickerDialog.OnDateSetListener{

        public DateDialogFragment()
        {
        }
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            Calendar cal=Calendar.getInstance();
            int year=cal.get(Calendar.YEAR);
            int month=cal.get(Calendar.MONTH);
            int day=cal.get(Calendar.DAY_OF_MONTH);
            return new DatePickerDialog(getActivity(), this, year, month, day);
        }
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            showSetDate(year,monthOfYear,dayOfMonth);
        }

        }

    public void showSetDate(int year,int month,int day) {
    text.setText(year+"/+"+month+"/"+day);
    }
}

Check this sample and implement the same in your Activity.

Using Alert Dialog:

Using the second one is pretty simple

Create layout in your res/layout folder and place DatePicker in the layout

 LayoutInflater  inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View view = (View) inflater.inflate(R.layout.yourlayout, null);
DatePicker picker=(DatePicker)view.findViewById(R.id.datepicker);

  AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
 builder.setView(view).
        builder.setMessage(R.string.dialog_fire_missiles)
               .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // FIRE ZE MISSILES!
                   }
               })
               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // User cancelled the dialog
                   }
               });
        // Create the AlertDialog object and return it
        return builder.create();

Solution 2

If you don't want to use a custom implementation of such dialog, you have to subclass DatePickerDialog to achieve such behavior. You can't block the dialog from closing just with DatePickerDialog.OnDateSetListener.

Unfortunatelly, implementations of the dialog vary with different API levels, so it's not that trivial to get the desired behavior with subclassing. You need to add some hacks to make it work reliably.

I've created a sample implementation that blocks the dialog from closing unless an appropriate date is set (or a cancel or back button is hit). Adjust it to display your alert to the users, the best place is the else branch in onClick() method.

class CheckingDatePickerDialog extends DatePickerDialog {

    private int year;
    private boolean cancel = false;
    private boolean isCancelable = true;

    CheckingDatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) {
        super(context, callBack, year, monthOfYear, dayOfMonth);
        this.year = year;
    }

    CheckingDatePickerDialog(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) {
        super(context, theme, callBack, year, monthOfYear, dayOfMonth);
        this.year = year;
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // allow closing the dialog with cancel button
        Button btn = getButton(BUTTON_NEGATIVE);
        if (btn != null) {
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    cancel = true;
                    dismiss();
                }
            });
        }
    }

    @Override
    public void setCancelable(boolean flag) {
        isCancelable = false;
        super.setCancelable(flag);
    }

    @Override
    public void onBackPressed() {
        // allow closing the dialog with back button if the dialog is cancelable
        cancel = isCancelable;
        super.onBackPressed();
    }

    private boolean isOldEnough() {
        // test if the date is allowed
        return year <= 1994;
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            // necessary for some Honeycomb devices
            DatePicker dp = getDatePicker();
            this.year = dp.getYear();
        }

        if (isOldEnough()) {
            // OnDateSetListener is called in super.onClick()
            super.onClick(dialog, which);  
        } else {
            // place your alert here
        }
    }

    @Override
    public void onDateChanged(DatePicker view, int year, int month, int day) {
        // on some Honeycomb devices called only with the first change
        // necessary for devices running Android 2.x
        this.year = year;
        super.onDateChanged(view, year, month, day);
    }

    @Override
    public void dismiss() {
        if (cancel || isOldEnough()) {
            // do not allow the dialog to be dismissed unless a cancel or back button was clicked
            super.dismiss();
        }
    }
};
Share:
16,956

Related videos on Youtube

vinothp
Author by

vinothp

Do what you like. Believe in what you do. Young and energetic individual with great passion on Mobile Application Development. Currently working as a full time mobile application developer for Android and iOS. In free time working on personal projects as well. My First Personal App - Location Plotter/ House Viewing

Updated on September 17, 2022

Comments

  • vinothp
    vinothp over 1 year

    I am using the following method to pop up the dialog to pick the date.

    private DatePickerDialog.OnDateSetListener mDateSetListener =
            new DatePickerDialog.OnDateSetListener() {
    
                public void onDateSet(DatePicker view, int year, 
                                      int monthOfYear, int dayOfMonth) {
                    dobYear = year;
                    dobMonth = monthOfYear;
                    dobDay = dayOfMonth;
                    if(isEighteenYearOld()){
                       //display the current date
                        dateDisplay();
                    } else{
                       Toast.makeText(mContext, "You must be 18 year old", Toast.LENGTH_SHORT).show();
                    }  
                } 
    
            };
    

    I know that onDateSet we can get the selected date. But what i am trying is if the date selected is younger than 18 years i need to alert the user. I have tried above code but it close the dialog and gone back to the activity.

    I want to stay in the dialog until user selects the date which is 18 years old.I am not sure how to get the onclick event in the dialog?

  • Pragnani
    Pragnani about 11 years
    @Vino use second approach, and in the onclick method get the selected date and check whether it is >18 or ..if true than close if not Post a error message
  • vinothp
    vinothp about 11 years
    Thanks for your suggestions Pragnani. I will try and let you know +1