SetMaxDate() отлично работает на Lollipop 5.0.1 android и нуждается в правильном решении

Даже после применения setMaxDate() к datepicker, я все еще могу выбрать отключенные даты на lollipop 5.0.1. Код работает отлично для всех других версий android, кроме lollipop 5.0.1.

Здесь, после ограничения дат, установив setMaxDate(), ни один пользователь не сможет выбрать отключенные даты. Как это сделать программно для DatePicker?

Я пробовал приведенный ниже код: -

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

Также я попытался найти решения, но они, похоже, не работают: -

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

и

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

и

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

Пожалуйста, предоставьте решение, которое работает на леденец на setMaxDate().

Или если у вас есть какой-либо другой ответ, попробуйте указать официальную цитату и ресурсы или ссылки (например, сайт разработчика Android), если вы знаете с краткой информацией. Спасибо заранее.

Ответ 1

Да, я нашел одну библиотеку wdullaer/MaterialDateTimePicker для datePicker, и она отлично работает в lollipop 5.0.1, как работа в другой версии API.

Ссылка для библиотеки решений Щелкните здесь для MaterialDateTimePicker

Добавьте эту библиотеку, добавив ниже строку в зависимостях {...} файла build.gradle (app).

compile 'com.wdullaer:materialdatetimepicker:3.2.1'

Затем реализуйте ниже код по мере необходимости: -

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

Ответ 2

Как уже указывалось в комментариях, нет действительно идеального решения для этого багги-календаря (на Android 5.0 вы можете выбрать недопустимую дату, а на некоторых устройствах Samsung странное поведение присутствовало: нажатие кнопки "Назад" фактически выбирало дату и другие что я действительно не помню). Однако я исправил проблему, когда вы можете выбрать недопустимую дату, проверив ее достоверность и отображая Toast в случае сбоя. Это НЕ ЗАПУСТИТ пользователя от фактического выбора недопустимой даты, а скорее заставит пользователя выбрать действительную дату, чтобы продолжить использование приложения.

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

Используя это, вы убедитесь, что если пользователь выберет недопустимую дату, вы дадите ему правильное предупреждающее сообщение и прекратите закрытие календаря, когда вы нажмете кнопку Ok. Функция validate должна быть создана в соответствии с вашими потребностями, но я думаю, что то, что у меня будет, будет прекрасно:

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

В качестве последнего слова я не гарантирую, что это лучшее решение, но я использовал его и не получал никаких жалоб от пользователей.

Ответ 3

Вам нужно добавить экземпляр Calender и использовать его как maxDate. Пожалуйста, добавьте в свой код следующую строку.

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