Accessibility Check fail when using TextInputLayout

27.9k views Asked by At

I'm using the new TextInputLayout provided by Android.support to do floating label. But it will fail Espresso Accessibility Check because "View is missing speakable text needed for a screen reader".

Looked into it and find out the TextInputLayout will nullify hint when parent does addView(). This is basically how it can float the label up(set the label, nullify the hint). And any EditText with null hint will fail the accessibility check.

Anyone knows how to resolve this issue? It's really driving me crazy..

Thanks a lot!!!!

5

There are 5 answers

2
MobA11y On BEST ANSWER

Hints aren't great for accessibility in general. They disappear when text is entered. Try using a "LabelFor" instead. If you don't want a visible label, you can set your label to not be displayed.

This app will give you hints on how to make text boxes accessible.

https://play.google.com/store/apps/details?id=com.dequesystems.accessibility101

0
Catalina On

Alternatively, if this is a false positive you can ignore checks as described here

val validator: AccessibilityValidator = AccessibilityChecks.enable().apply {
setSuppressingResultMatcher(
        allOf(
                matchesCheckNames(`is`("TouchTargetSizeViewCheck")),
                matchesViews(withId(R.id.my_overflow))
        )
)}

The following rules are invoked when we enable tests for accessibility checks:

  • TouchTargetSizeViewCheck Target height or target width less than 48 dp is flagged, unless there is a touchdelegate detected.
  • TextContrastViewCheck Checks text color and background and factors in large text, and calculates the contrast ratio: - 4.5 for regular text, 3 for large text.
  • DuplicateSpeakableTextViewHierarchyCheck If two Views in a hierarchy have the same speakable text, that could be confusing for users if at least one of them is clickable.
  • SpeakableTextPresentViewCheck If the view is focusable, this checks whether valid speakable text exists, and errors if the view is missing speakable text needed for a screen reader.
  • EditableContentDescViewCheck Throws an error if Editable TextView has a contentDescription.
  • ClickableSpanViewCheck Checks if ClickableSpan is inaccessible. Individual spans cannot be selected independently in a single TextView, and accessibility services are unable to call ClickableSpan#onClick.
  • RedundantContentDescViewCheck Accessibility services are aware of the view's type and can use that information as needed. For example, it throws a warning if the content description has a redundant word, such as “button.”
  • DuplicateClickableBoundsViewCheck Throws an error if Clickable view has the same bounds as another clickable view (likely a descendent). Sometimes there are containers marked clickable, and they don't process any click events.
0
Jeff Padgett On

You can make a TextView that has

android:text="My Announcement For Edit Text"
android:labelFor="@id/my_edit_text".

Visibility = gone and visibility = invisible will make it so this label is not announced. Also if you set height and width to 0dp, this will not announce. Instead, constrain the view to be off the screen using something like:

app:layout_constraintEnd_toStartOf="parent"

So your textview will look like this:

<TextView
        android:id="@+id/edit_text_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:labelFor="@+id/my_edit_text"
        android:text="Label For My Edit Text"
        app:layout_constraintEnd_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
0
Murli On

This worked for me using withClassName for a view

AccessibilityChecks.enable().setSuppressingResultMatcher(
        AccessibilityCheckResultUtils.matchesViews(
            Matchers.anyOf(
                ViewMatchers.withResourceName("textview1"),
                ViewMatchers.withResourceName("button1"),
                ViewMatchers.withClassName(Matchers.endsWith("TextInputLayout"))
            )
        )
    )
3
ArnaudR On

A great way to make TextInputLayout accessible is to use "LabelFor" as recommanded by ChrisCM, but you don't have to add an invisible label view to do so: Just put the labelFor or your Textinputlayout and make it point to your EditText

Example:

<android.support.design.widget.TextInputLayout
  android:labelFor="@+id/username"
  android:contentDescription="@string/username_hint"
  android:accessibilityLiveRegion="polite">
    <edittext
      android:id="@+id/username"
      android:hint="@string/username_hint"
       …/>
</android.support.design.widget.TextInputLayout>

This way you get the exact same visual behaviour and make "Espresso Accessibility Check" and Talkback happy :)

(To make TextInputLayout fully accessible I also added android:accessibilityliveregion on the TextInputLayout element to trigger talkback whenever the error is poping)

A big thanks to this post this blog post which helped a lot