11

How to add a constraint to MaterialDatePicker to force user to select a date between only 2 dates?

val constraintBuilder = CalendarConstraints.Builder()
    val materialRangeBuilder = MaterialDatePicker.Builder.datePicker()
    materialRangeBuilder.setTitleText("Book Date")
    materialRangeBuilder.setCalendarConstraints(constraintBuilder.build())

    val materialRangePicker = materialRangeBuilder.build()

    materialRangePicker.addOnPositiveButtonClickListener {
        Timber.d("$it")
    }

    materialRangePicker.show(supportFragmentManager, "DATE_RANGE_PICKER")
Edric
  • 24,639
  • 13
  • 81
  • 91
Ahmed Abdeen
  • 325
  • 5
  • 14

5 Answers5

19

You can use a DateValidator to restrict the selections.
In particular you can use the built-in validators:

  • DateValidatorPointForward that enables dates from a given point forward
  • DateValidatorPointBackward that enables only dates before a given point.

Something like:

MaterialDatePicker.Builder<Long> builder = MaterialDatePicker.Builder.datePicker();

CalendarConstraints.Builder constraintsBuilderRange = new CalendarConstraints.Builder();

//....define min and max for example with LocalDateTime and ZonedDateTime or Calendar

CalendarConstraints.DateValidator dateValidatorMin = DateValidatorPointForward.from(min.getTimeInMillis());
CalendarConstraints.DateValidator dateValidatorMax = DateValidatorPointBackward.before(max.getTimeInMillis());

ArrayList<CalendarConstraints.DateValidator> listValidators =
            new ArrayList<CalendarConstraints.DateValidator>();
listValidators.add(dateValidatorMin);
listValidators.add(dateValidatorMax);
CalendarConstraints.DateValidator validators = CompositeDateValidator.allOf(listValidators);
constraintsBuilderRange.setValidator(validators);

builder.setCalendarConstraints(constraintsBuilderRange.build());

MaterialDatePicker<Long> picker = builder.build();
picker.show(getSupportFragmentManager(), picker.toString());

enter image description here

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
6

This is version for kotlin :

private fun calendarConstraints(): CalendarConstraints {
    val dateValidatorMin: DateValidator = DateValidatorPointForward.from(min.getTimeInMillis())
    val dateValidatorMax: DateValidator = DateValidatorPointBackward.before(max.getTimeInMillis())

    val listValidators = ArrayList<DateValidator>()
    listValidators.apply {
        add(dateValidatorMin)
        add(dateValidatorMax)
    }
    val validators = CompositeDateValidator.allOf(listValidators)

    return CalendarConstraints.Builder()
        .setValidator(validators)
        .build()
}
private fun setupCalendar() {
   val materialDatePickerBuilder = MaterialDatePicker.Builder.datePicker().setCalendarConstraints(calendarConstraints())}
3

@GabrieleMariotti answer is good, but DateValidatorPointBackwards class is not in material design library before version 1.2. If you want to choose between two dates and you have material design library version 1.1 or earlier, you can do it like this:

val datePickerBuilder = MaterialDatePicker.Builder.datePicker()
datePickerBuilder.setCalendarConstraints(
    CalendarConstraints.Builder()
        .setValidator(object : CalendarConstraints.DateValidator {
            override fun isValid(date: Long): Boolean {
                return date >= startDate && date < endDate
            }

            override fun writeToParcel(p0: Parcel?, p1: Int) {}

            override fun describeContents(): Int {return 0}
        }).build()
)
val datePicker = datePickerBuilder.build()
datePicker!!.show(fragmentManager, "date picker")

where startDate and endDate are long values

0

update build.gradle (app) version as below

implementation 'com.google.android.material:material:1.4.0'

code level

CalendarConstraints.Builder constraintsBuilderRange = new CalendarConstraints.Builder()
                .setValidator(DateValidatorPointBackward.now());
        builder.setCalendarConstraints(constraintsBuilderRange.build());
        MaterialDatePicker picker = builder.build();
Samsul Huq
  • 21
  • 2
-1

Use these two methods

public void setMinDate (long minDate)
public void setMaxDate (long maxDate)

Here is the official documentation. https://developer.android.com/reference/android/widget/DatePicker#setMaxDate(long)

Example

val calender = Calendar.getInstance()
val year = calender.get(Calendar.YEAR)
val month = calender.get(Calendar.MONTH)
val day = calender.get(Calendar.DAY_OF_MONTH)
materialRangeBuilder.setMinDate(calender.getTimeInMillis())
materialRangeBuilder.setMaxDate(calender.getTimeInMillis())
Nauman Khaliq
  • 909
  • 5
  • 2