Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setMaxDate() not working perfectly on Lollipop 5.0.1 android and need proper solution

Even after applying setMaxDate() to datepicker, I am still able to select the disabled dates on lollipop 5.0.1. The code is working fine for all other versions of android except for lollipop 5.0.1.

Here after restricting the dates by setting setMaxDate(), no user should be able to select disabled dates. How can I achieve this programmatically for DatePicker?

I have tried the below code:-

datePickerDialog = new DatePickerDialog(myContext, new DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
        }
    }, mYear, mMonth, mDay);
    datePickerDialog.getDatePicker().setMaxDate(System.currentTimeMillis());
    datePickerDialog.setCanceledOnTouchOutside(true);
    datePickerDialog.setCancelable(true);
    datePickerDialog.show();

Also I tried below solutions but these don't seem to work:-

datePickerDialog.getDatePicker().setMaxDate(System.currentTimeMillis());

and

Calendar maxCal = Calendar.getInstance();
datePickerDialog.getDatePicker().setMaxDate(maxCal.getTimeInMillis());

and

Date maxDate = new Date();
datePickerDialog.getDatePicker().setMaxDate(maxDate.getTime());

Please provide solution which is working for lollipop to setMaxDate().

Or if you have any other answer, please try to include official quote and resources or links (like android developer site) if you know with brief details. Thanks in advance.

like image 806
Nitin Patel Avatar asked May 11 '17 06:05

Nitin Patel


3 Answers

As already pointed in comments, there is no really perfect solution for this buggy calendar(on Android 5.0 you can select an invalid date and on some Samsung devices a strange behaviour was present: pressing back button was actually selecting a date and others that I don't really remember). However, I fixed the problem when you can select an invalid date by checking its validity and displaying a Toast in case of failure. This will NOT STOP the user from actually selecting an invalid date, but rather force the user to select a valid date in order to continue using the app.

   DatePickerDialog dialog = new DatePickerDialog(getActivity(), mOnDateSetListener, year, month, day) {
        private boolean allowClose = false;

        @Override
        public void onBackPressed() {
            allowClose = true;
            super.onBackPressed();
        }

        @Override
        public void onClick(DialogInterface dialog, int which) {
            allowClose = true;
            if (which == DialogInterface.BUTTON_POSITIVE && !validate()) {
                allowClose = false;
                Toast.makeText(getContext(), R.string.invalid_date, Toast.LENGTH_SHORT).show();
            }
            if (allowClose) {
                super.onClick(dialog, which);
            }
        }

        @Override
        public void dismiss() {
            if (allowClose) {
                super.dismiss();
            }
        }
    };

By using this, you make sure that if the user select an invalid date, you will give him a proper warning message and stop the calendar from closing when you press the Ok button. The validate function should be created to fit your needs, but I think that what I have will do just fine:

private boolean validate() {
    if (this.getDialog() instanceof DatePickerDialog) {
        DatePicker datePicker = ((DatePickerDialog) this.getDialog()).getDatePicker();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, datePicker.getYear());
        calendar.set(Calendar.MONTH, datePicker.getMonth());
        calendar.set(Calendar.DAY_OF_MONTH, datePicker.getDayOfMonth());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        boolean valid = false;
        Calendar minCalendar = Calendar.getInstance();
        minCalendar.setTimeInMillis(datePicker.getMinDate());
        Calendar maxCalendar = Calendar.getInstance();
        maxCalendar.setTimeInMillis(datePicker.getMaxDate());
        if (DateUtils.in(calendar.getTime(), minCalendar.getTime(), maxCalendar.getTime())) {
            valid = true;
        }
        return valid;
    }
    return false;
}

As a final word, I don't guarantee that this is the best solution, but I had used it and didn't received any complains from users.

like image 76
Iulian Popescu Avatar answered Oct 16 '22 21:10

Iulian Popescu


Yes, I have found one library wdullaer/MaterialDateTimePicker for datePicker and it is working perfectly in lollipop 5.0.1 just like work in other API version.

The link for solution library is Click Here For MaterialDateTimePicker

Add this library by adding below line in dependencies{...} of build.gradle(app) file.

compile 'com.wdullaer:materialdatetimepicker:3.2.1'

Then implement below code as per need:-

MainActivity mainActivity = (MainActivity) myContext;
    final DatePickerDialog dpd = DatePickerDialog.newInstance(
            new DatePickerDialog.OnDateSetListener() {
                @Override
                public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
                    //To do your task here
                }
            },
            mYear,
            mMonth,
            mDay
    );
    dpd.setVersion(DatePickerDialog.Version.VERSION_2);
    dpd.setMaxDate(Calendar.getInstance());
    dpd.show(mainActivity.getFragmentManager(), "Datepickerdialog");
like image 3
Nitin Patel Avatar answered Oct 16 '22 22:10

Nitin Patel


You need to add Calender Instance and use it as maxDate. Please refer line added in your code below.

datePickerDialog = new DatePickerDialog(myContext, new DatePickerDialog.OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
    }
}, mYear, mMonth, mDay);

Calendar maxCal = Calendar.getInstance();

datePickerDialog.getDatePicker().setMaxDate(maxCal.getTimeInMillis());
datePickerDialog.setCanceledOnTouchOutside(true);
datePickerDialog.setCancelable(true);
datePickerDialog.show();
like image 2
SilverSky Avatar answered Oct 16 '22 21:10

SilverSky