Home » Android » android – Accessibility Check fail when using TextInputLayout

android – Accessibility Check fail when using TextInputLayout

Posted by: admin June 15, 2020 Leave a comment

Questions:

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!!!!

How to&Answers:

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

Answer:

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


Answer:

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.

Answer:

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"
        />