Skip to content

Commit e664b98

Browse files
committed
[MaterialDatePicker] Crash - Scroll to Min Year of CalendarConstraint
Resolves #981 Resolves #980 PiperOrigin-RevId: 296000173
1 parent 7b165f8 commit e664b98

File tree

3 files changed

+66
-3
lines changed

3 files changed

+66
-3
lines changed

lib/java/com/google/android/material/datepicker/CalendarConstraints.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,21 @@ public void writeToParcel(Parcel dest, int flags) {
167167
dest.writeParcelable(validator, /* parcelableFlags = */ 0);
168168
}
169169

170+
/**
171+
* Returns the given month if it's within the constraints or the closest bound if it's outside.
172+
*/
173+
Month clamp(Month month) {
174+
if (month.compareTo(start) < 0) {
175+
return start;
176+
}
177+
178+
if (month.compareTo(end) > 0) {
179+
return end;
180+
}
181+
182+
return month;
183+
}
184+
170185
/** Builder for {@link com.google.android.material.datepicker.CalendarConstraints}. */
171186
public static final class Builder {
172187

lib/java/com/google/android/material/datepicker/YearGridAdapter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ private OnClickListener createYearClickListener(final int year) {
8484
return new OnClickListener() {
8585
@Override
8686
public void onClick(View view) {
87-
Month moveTo = Month.create(year, materialCalendar.getCurrentMonth().month);
87+
Month current = Month.create(year, materialCalendar.getCurrentMonth().month);
88+
CalendarConstraints calendarConstraints = materialCalendar.getCalendarConstraints();
89+
Month moveTo = calendarConstraints.clamp(current);
8890
materialCalendar.setCurrentMonth(moveTo);
8991
materialCalendar.setSelector(CalendarSelector.DAY);
9092
}

lib/javatests/com/google/android/material/datepicker/CalendarConstraintsTest.java

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package com.google.android.material.datepicker;
1717

18+
import static com.google.common.truth.Truth.assertThat;
1819
import static org.junit.Assert.assertEquals;
1920

2021
import com.google.android.material.internal.ParcelableTestUtils;
@@ -24,10 +25,9 @@
2425
import org.junit.rules.ExpectedException;
2526
import org.junit.runner.RunWith;
2627
import org.robolectric.RobolectricTestRunner;
27-
import org.robolectric.annotation.internal.DoNotInstrument;
2828

29+
/** Tests for {@link CalendarConstraints} */
2930
@RunWith(RobolectricTestRunner.class)
30-
@DoNotInstrument
3131
public class CalendarConstraintsTest {
3232

3333
private static final long FEB_2016 = Month.create(2016, Calendar.FEBRUARY).timeInMillis;
@@ -45,6 +45,52 @@ public void equalAfterParceling() {
4545
assertEquals(originalBounds, constructedBounds);
4646
}
4747

48+
@Test
49+
public void clampMonth_when_InsideBounds() {
50+
Month today = Month.today();
51+
Month yearBefore = today.monthsLater(-12);
52+
Month yearAfter = today.monthsLater(12);
53+
54+
long start = yearBefore.timeInMillis;
55+
long end = yearAfter.timeInMillis;
56+
CalendarConstraints calendarConstraints =
57+
new CalendarConstraints.Builder().setStart(start).setEnd(end).build();
58+
59+
Month monthWithinBounds = yearAfter.monthsLater(-5);
60+
assertThat(calendarConstraints.clamp(monthWithinBounds))
61+
.isEqualTo(monthWithinBounds);
62+
}
63+
64+
@Test
65+
public void clampMonth_when_beforeLowerBound() {
66+
Month today = Month.today();
67+
Month yearBefore = today.monthsLater(-12);
68+
Month yearAfter = today.monthsLater(12);
69+
70+
long start = yearBefore.timeInMillis;
71+
long end = yearAfter.timeInMillis;
72+
CalendarConstraints calendarConstraints =
73+
new CalendarConstraints.Builder().setStart(start).setEnd(end).build();
74+
75+
assertThat(calendarConstraints.clamp(yearBefore.monthsLater(-5)))
76+
.isEqualTo(yearBefore);
77+
}
78+
79+
@Test
80+
public void clampMonth_when_AfterUpperBound() {
81+
Month today = Month.today();
82+
Month yearBefore = today.monthsLater(-12);
83+
Month yearAfter = today.monthsLater(12);
84+
85+
long start = yearBefore.timeInMillis;
86+
long end = yearAfter.timeInMillis;
87+
CalendarConstraints calendarConstraints =
88+
new CalendarConstraints.Builder().setStart(start).setEnd(end).build();
89+
90+
assertThat(calendarConstraints.clamp(yearAfter.monthsLater(5)))
91+
.isEqualTo(yearAfter);
92+
}
93+
4894
@Test
4995
public void currentDefaultsToTodayIfWithinBounds() {
5096
Month today = Month.today();

0 commit comments

Comments
 (0)