[DatePicker] Fix Talkback issues with the hint text by adding a TtsSpan.TYPE_VERBATIM so that the hints are read as verbatim text by screen readers.

PiperOrigin-RevId: 776123945
This commit is contained in:
kendricku 2025-06-26 14:10:17 +00:00 committed by Hunter Stich
parent 05dc80584a
commit 7c162ef28c
4 changed files with 33 additions and 3 deletions

View File

@ -23,6 +23,7 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.InputType;
import android.text.SpannableString;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
@ -251,8 +252,10 @@ public class RangeDateSelector implements DateSelector<Pair<Long, Long>> {
? format.toPattern()
: UtcDates.getDefaultTextInputHint(root.getResources(), format);
startTextInput.setPlaceholderText(formatHint);
endTextInput.setPlaceholderText(formatHint);
SpannableString verbatimHint = UtcDates.getVerbatimTextInputHint(formatHint);
startTextInput.setPlaceholderText(verbatimHint);
endTextInput.setPlaceholderText(verbatimHint);
startEditText.addTextChangedListener(
new DateFormatTextWatcher(formatHint, format, startTextInput, constraints) {

View File

@ -132,7 +132,7 @@ public class SingleDateSelector implements DateSelector<Long> {
? format.toPattern()
: UtcDates.getDefaultTextInputHint(root.getResources(), format);
dateTextInput.setPlaceholderText(formatHint);
dateTextInput.setPlaceholderText(UtcDates.getVerbatimTextInputHint(formatHint));
if (selectedItem != null) {
dateEditText.setText(format.format(selectedItem));
// Move the cursor to the end of the text field

View File

@ -21,6 +21,9 @@ import android.annotation.TargetApi;
import android.content.res.Resources;
import android.icu.text.DisplayContext;
import android.os.Build.VERSION_CODES;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.TtsSpan;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.text.DateFormat;
@ -180,6 +183,20 @@ class UtcDates {
return formatHint.replace("d", dayChar).replace("M", monthChar).replace("y", yearChar);
}
/**
* Returns a SpannableString with the given format hint that has a TtsSpan.TYPE_VERBATIM span
* applied to it in order to ensure that the hint is read verbatim by screen readers.
*/
static SpannableString getVerbatimTextInputHint(String formatHint) {
SpannableString spannableHint = new SpannableString(formatHint);
spannableHint.setSpan(
new TtsSpan.Builder(TtsSpan.TYPE_VERBATIM).build(),
0,
spannableHint.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannableHint;
}
/**
* Receives a given local date format string and returns a string that can be displayed to the
* user and parsed by the date parser.

View File

@ -21,6 +21,7 @@ import static org.junit.Assert.assertEquals;
import android.content.Context;
import androidx.appcompat.app.AppCompatActivity;
import android.text.SpannableString;
import androidx.test.core.app.ApplicationProvider;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
@ -87,6 +88,15 @@ public class UtcDatesTest {
assertEquals("년.월.일.", hint);
}
@Test
public void verbatimTextInputHintForUK() {
SimpleDateFormat sdf = new SimpleDateFormat("dd/mm/yyyy", Locale.UK);
String hint = UtcDates.getDefaultTextInputHint(context.getResources(), sdf);
SpannableString hintSpannable = UtcDates.getVerbatimTextInputHint(hint);
assertEquals("dd/mm/yyyy", hintSpannable.toString());
}
@Test
public void normalizeTextInputFormat() {
SimpleDateFormat sdf = new SimpleDateFormat("M/d/y");