Skip to content

Commit b690127

Browse files
leticiarossihunterstich
authored andcommitted
[TextInputLayout][a11y] Fixed prefix/suffix not being properly announced when the text field is focused and they show up. Also improved their screen reader focus order to align with the visual order of the elements: navigating to the left will focus on the prefix and navigating to the right will focus on the suffix.
Resolves #2497 PiperOrigin-RevId: 430208388
1 parent 45841c9 commit b690127

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

lib/java/com/google/android/material/textfield/TextInputLayout.java

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2549,8 +2549,11 @@ public TextView getPrefixTextView() {
25492549
}
25502550

25512551
private void updatePrefixTextVisibility() {
2552-
prefixTextView.setVisibility((prefixText != null && !isHintExpanded()) ? VISIBLE : GONE);
2552+
int visibility = (prefixText != null && !isHintExpanded()) ? VISIBLE : GONE;
25532553
updateStartLayoutVisibility();
2554+
// Set visibility after updating start layout's visibility so screen readers correctly announce
2555+
// when prefix text appears.
2556+
prefixTextView.setVisibility(visibility);
25542557
updateDummyDrawables();
25552558
}
25562559

@@ -2636,13 +2639,15 @@ public TextView getSuffixTextView() {
26362639
}
26372640

26382641
private void updateSuffixTextVisibility() {
2639-
int oldSuffixVisibility = suffixTextView.getVisibility();
2640-
boolean visible = suffixText != null && !isHintExpanded();
2641-
suffixTextView.setVisibility(visible ? VISIBLE : GONE);
2642-
if (oldSuffixVisibility != suffixTextView.getVisibility()) {
2643-
getEndIconDelegate().onSuffixVisibilityChanged(visible);
2642+
int oldVisibility = suffixTextView.getVisibility();
2643+
int newVisibility = (suffixText != null && !isHintExpanded()) ? VISIBLE : GONE;
2644+
if (oldVisibility != newVisibility) {
2645+
getEndIconDelegate().onSuffixVisibilityChanged(/* visible= */ newVisibility == VISIBLE);
26442646
}
26452647
updateEndLayoutVisibility();
2648+
// Set visibility after updating end layout's visibility so screen readers correctly announce
2649+
// when suffix text appears.
2650+
suffixTextView.setVisibility(newVisibility);
26462651
updateDummyDrawables();
26472652
}
26482653

@@ -3976,15 +3981,17 @@ private void updateEndLayoutVisibility() {
39763981
endIconFrame.setVisibility(
39773982
(endIconView.getVisibility() == VISIBLE && !isErrorIconVisible()) ? VISIBLE : GONE);
39783983

3984+
int suffixTextVisibility = (suffixText != null && !isHintExpanded()) ? VISIBLE : GONE;
39793985
boolean shouldBeVisible =
3980-
isEndIconVisible() || isErrorIconVisible() || suffixTextView.getVisibility() == VISIBLE;
3986+
isEndIconVisible() || isErrorIconVisible() || suffixTextVisibility == VISIBLE;
39813987
endLayout.setVisibility(shouldBeVisible ? VISIBLE : GONE);
39823988
}
39833989

39843990
private void updateStartLayoutVisibility() {
39853991
// Set startLayout to visible if start icon or prefix text is present.
3992+
int prefixTextVisibility = (prefixText != null && !isHintExpanded()) ? VISIBLE : GONE;
39863993
boolean shouldBeVisible =
3987-
startIconView.getVisibility() == VISIBLE || prefixTextView.getVisibility() == VISIBLE;
3994+
startIconView.getVisibility() == VISIBLE || prefixTextVisibility == VISIBLE;
39883995
startLayout.setVisibility(shouldBeVisible ? VISIBLE : GONE);
39893996
}
39903997

@@ -4598,9 +4605,18 @@ public void onInitializeAccessibilityNodeInfo(
45984605
boolean isHintCollapsed = !layout.isHintExpanded();
45994606
boolean showingError = !TextUtils.isEmpty(errorText);
46004607
boolean contentInvalid = showingError || !TextUtils.isEmpty(counterOverflowDesc);
4601-
4608+
boolean isShowingPrefixText = layout.getPrefixTextView().getVisibility() == VISIBLE;
46024609
String hint = hasHint ? hintText.toString() : "";
46034610

4611+
// Screen readers should follow visual order of the elements of the text field.
4612+
if (isShowingPrefixText) {
4613+
info.setLabelFor(layout.getPrefixTextView());
4614+
info.setTraversalAfter(layout.getPrefixTextView());
4615+
} else {
4616+
info.setTraversalAfter(layout.startIconView);
4617+
}
4618+
4619+
// Make sure text field has the appropriate announcements.
46044620
if (showingText) {
46054621
info.setText(inputText);
46064622
} else if (!TextUtils.isEmpty(hint)) {

0 commit comments

Comments
 (0)