Android DatePickerDialog: установите минимальную и максимальную дату для выбора

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

public class DatePickerDialogFragment extends DialogFragment {

    private OnDateSetListener listener;

    public void setListener(OnDateSetListener listener) {
        this.listener = listener;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Calendar calendar = Calendar.getInstance();
        int year    = calendar.get(Calendar.YEAR);
        int month   = calendar.get(Calendar.MONTH);
        int day     = calendar.get(Calendar.DAY_OF_MONTH);

        DatePickerDialog dialog = new DatePickerDialog(getContext(), listener, year, month, day);
        dialog.getDatePicker().setMinDate(calendar.getTimeInMillis());
        return dialog;
    }
}

я показываю это как:

DatePickerDialogFragment fragment = new DatePickerDialogFragment();
fragment.setListener(dateSetListener);
fragment.show(getSupportFragmentManager(), "Choose booking date");

Я хочу, чтобы пользователь не мог выбрать дату до сегодняшнего дня. Как видите, я позвонил setMinDate() метод с сегодняшним временем, но это как не влияет. Диалоговое окно показывает даты до сегодняшнего дня как серые, но выбираемые.

Я также пытался подкласс DatePickerDialog и заменить onDateChanged как предложено в некоторых ответах stackoverflow, но без успеха.

4 ответов


попробуйте этот метод

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Calendar calendar = Calendar.getInstance();
    int year    = calendar.get(Calendar.YEAR);
    int month   = calendar.get(Calendar.MONTH);
    int day     = calendar.get(Calendar.DAY_OF_MONTH);

    DatePickerDialog dialog = new DatePickerDialog(getContext(), listener, year, month, day);
    Field mDatePickerField;
    try {
            mDatePickerField = dialog.getClass().getDeclaredField("mDatePicker");
            mDatePickerField.setAccessible(true);
    } catch (Exception e) {
            e.printStackTrace();
    }
    dialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
    return dialog;
}

вместо

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Calendar calendar = Calendar.getInstance();
    int year    = calendar.get(Calendar.YEAR);
    int month   = calendar.get(Calendar.MONTH);
    int day     = calendar.get(Calendar.DAY_OF_MONTH);

    DatePickerDialog dialog = new DatePickerDialog(getContext(), listener, year, month, day);
    dialog.getDatePicker().setMinDate(calendar.getTimeInMillis());
    return dialog;
}

EDIT1:

Я также столкнулся с этой проблемой, что пользователь может выбрать не выбираемые даты в Android L 5.0.2. В настоящее время сообщается об ошибке здесь. Он решается в Android L 5.1.0.

для временного решения этой проблемы вы можете сравнить выбранную дату с текущей системной датой и поставить на ее основе условие. Я использовал это как обходной путь

EDIT2:

добавить onDateSent() метод DatePickerDialogFragment и просто проверьте, если это раньше, чем дата, которую вы установили в setMinDate(). Если да, то просто покажите DatePickerDialog снова.

final long today = System.currentTimeMillis() - 1000;

@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            Calendar calendar = Calendar.getInstance();
            calendar.set(year, monthOfYear, dayOfMonth);
            //If user tries to select date in past (or today)
            if (calendar.getTimeInMillis() < today)
            {
                //Make them try again
               DatePickerDialogFragment fragment = new DatePickerDialogFragment();
               fragment.setListener(dateSetListener);
               fragment.show(getSupportFragmentManager(), "Choose booking date");
               Toast.makeText(this, "Invalid date, please try again", Toast.LENGTH_LONG).show();
            }
            else
            {
                //success
            }
}

получить системное время и вычесть из него 1 секунду

 @Override
 public Dialog onCreateDialog(Bundle savedInstanceState) {
    Calendar calendar = Calendar.getInstance();
    int year    = calendar.get(Calendar.YEAR);
    int month   = calendar.get(Calendar.MONTH);
    int day     = calendar.get(Calendar.DAY_OF_MONTH);

     dialog = new DatePickerDialog(act, listener, year, month, day);
     dialog.getDatePicker().setMinDate(System.currentTimeMillis() -1000);
     return dialog;
 }

dialog.getDatePicker().setMinDate(calendar.getTimeInMillis());

выше API 11 для минимальной даты вы можете использовать

android:minDate="mm/dd/yyyy" или setMinDate(long time) Для Max дата

android:maxDate="mm/dd/yyyy" // в XML

setMaxDate(new Date().getTime());// настоящее время