Skip to content

Commit 71287c6

Browse files
Material Design Teampaulfthomas
Material Design Team
authored andcommitted
[MaterialDatePicker][A11y] Disable next/prev button when the selected month is at the boundary
When user clicks on previous/next month button, the button will be disabled if the clicked month is at the boundary. PiperOrigin-RevId: 738309727
1 parent 9c33476 commit 71287c6

File tree

2 files changed

+62
-7
lines changed

2 files changed

+62
-7
lines changed

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

+16-7
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ void setCurrentMonth(Month moveTo) {
347347
} else {
348348
postSmoothRecyclerViewScroll(moveToPosition);
349349
}
350+
updateNavigationButtonsEnabled(moveToPosition);
350351
}
351352

352353
@Nullable
@@ -442,8 +443,12 @@ public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
442443
} else {
443444
currentItem = getLayoutManager().findLastVisibleItemPosition();
444445
}
445-
current = monthsPagerAdapter.getPageMonth(currentItem);
446+
Month moveToMonth = monthsPagerAdapter.getPageMonth(currentItem);
447+
current = moveToMonth;
446448
monthDropSelect.setText(monthsPagerAdapter.getPageTitle(currentItem));
449+
450+
int currentMonthPosition = monthsPagerAdapter.getPosition(moveToMonth);
451+
updateNavigationButtonsEnabled(currentMonthPosition);
447452
}
448453

449454
@Override
@@ -468,21 +473,25 @@ public void onClick(View view) {
468473
@Override
469474
public void onClick(View view) {
470475
int currentItem = getLayoutManager().findFirstVisibleItemPosition();
471-
if (currentItem + 1 < recyclerView.getAdapter().getItemCount()) {
472-
setCurrentMonth(monthsPagerAdapter.getPageMonth(currentItem + 1));
473-
}
476+
setCurrentMonth(monthsPagerAdapter.getPageMonth(currentItem + 1));
474477
}
475478
});
476479
monthPrev.setOnClickListener(
477480
new OnClickListener() {
478481
@Override
479482
public void onClick(View view) {
480483
int currentItem = getLayoutManager().findLastVisibleItemPosition();
481-
if (currentItem - 1 >= 0) {
482-
setCurrentMonth(monthsPagerAdapter.getPageMonth(currentItem - 1));
483-
}
484+
setCurrentMonth(monthsPagerAdapter.getPageMonth(currentItem - 1));
484485
}
485486
});
487+
488+
int currentMonthPosition = monthsPagerAdapter.getPosition(current);
489+
updateNavigationButtonsEnabled(currentMonthPosition);
490+
}
491+
492+
private void updateNavigationButtonsEnabled(int currentMonthPosition) {
493+
monthNext.setEnabled(currentMonthPosition + 1 < recyclerView.getAdapter().getItemCount());
494+
monthPrev.setEnabled(currentMonthPosition - 1 >= 0);
486495
}
487496

488497
private void postSmoothRecyclerViewScroll(final int position) {

tests/javatests/com/google/android/material/datepicker/MaterialDatePickerPagesTest.java

+46
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,14 @@
1515
*/
1616
package com.google.android.material.datepicker;
1717

18+
import static androidx.test.espresso.Espresso.onView;
19+
import static androidx.test.espresso.assertion.ViewAssertions.matches;
20+
import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
21+
import static androidx.test.espresso.matcher.ViewMatchers.withTagValue;
1822
import static com.google.android.material.datepicker.MaterialDatePickerTestUtils.findFirstVisibleItem;
1923
import static org.hamcrest.Matchers.lessThan;
24+
import static org.hamcrest.Matchers.not;
25+
import static org.hamcrest.core.IsEqual.equalTo;
2026
import static org.junit.Assert.assertEquals;
2127
import static org.junit.Assert.assertFalse;
2228
import static org.junit.Assert.assertThat;
@@ -141,4 +147,44 @@ public void accessibility_daySelection_notScrollable() {
141147

142148
assertFalse(nodeInfo.isScrollable());
143149
}
150+
151+
@Test
152+
public void previousButtonDisabledAtStartBoundary() {
153+
MaterialDatePickerTestUtils.clickPrev();
154+
onView(withTagValue(equalTo(MaterialCalendar.NAVIGATION_PREV_TAG)))
155+
.check(matches(not(isEnabled())));
156+
}
157+
158+
@Test
159+
public void nextButtonDisabledAtEndBoundary() {
160+
MaterialDatePickerTestUtils.clickNext();
161+
MaterialDatePickerTestUtils.clickNext();
162+
MaterialDatePickerTestUtils.clickNext();
163+
onView(withTagValue(equalTo(MaterialCalendar.NAVIGATION_NEXT_TAG)))
164+
.check(matches(not(isEnabled())));
165+
}
166+
167+
@Test
168+
public void nextButtonEnabledAtStartBoundary() {
169+
MaterialDatePickerTestUtils.clickPrev();
170+
onView(withTagValue(equalTo(MaterialCalendar.NAVIGATION_NEXT_TAG)))
171+
.check(matches(isEnabled()));
172+
}
173+
174+
@Test
175+
public void previousButtonEnabledAtEndBoundary() {
176+
MaterialDatePickerTestUtils.clickNext();
177+
MaterialDatePickerTestUtils.clickNext();
178+
MaterialDatePickerTestUtils.clickNext();
179+
onView(withTagValue(equalTo(MaterialCalendar.NAVIGATION_PREV_TAG)))
180+
.check(matches(isEnabled()));
181+
}
182+
183+
@Test
184+
public void navigationButtonsEnabledInMiddleOfBoundary() {
185+
onView(withTagValue(equalTo(MaterialCalendar.NAVIGATION_NEXT_TAG)))
186+
.check(matches(isEnabled()));
187+
onView(withTagValue(equalTo(MaterialCalendar.NAVIGATION_NEXT_TAG)))
188+
.check(matches(isEnabled()));
189+
}
144190
}

0 commit comments

Comments
 (0)