Michal Urbanek4 min

Accessibility at STRV: Android Best Practices

EngineeringOct 20, 2021

Engineering

/

Oct 20, 2021

Michal UrbanekAndroid Engineer

Share this article

In our previous Accessibility (a11y) in Android Apps articles, we covered most common topics and issues. If you’ve already dealt with those, then passing any accessibility review check should be way easier for you.

This time around, we’d like to go over some extra issues and best practices based on our own experiences.

And just in case you haven’t read our previous articles, we recommend checking them out — starting with​ what Digital Accessibility is and why it matters and moving into the Basics & Tools of Accessibility in Android Apps, Part 1 and Part 2.

Use Material Design Components Whenever Possible

This will save you a lot of time and also fixes a lot of issues related to a11y. Proper styling and component usage are key for smoother working with a11y and for further improvements.

Example of a password input field where all the work is done automatically:

<com.google.android.material.textfield.TextInputLayout
   android:hint="@string/password"
   app:errorEnabled="true"
   app:passwordToggleEnabled="true">

   <com.google.android.material.textfield.TextInputEditText
       android:autofillHints="password"
       android:inputType="textPassword"
       tools:text="Some password" />
</com.google.android.material.textfield.TextInputLayout>

Use Proper Widgets for Any Given Work

At first glance, it may look the same and also behave the same, but using a screen reader may result in issues when the component class is spoken.

Nicely styleable Toggle Group where each 'tab' is made of buttons. But the screen reader then reads those 'tabs' as buttons with no other context:

<com.google.android.material.button.MaterialButtonToggleGroup>
    <com.google.android.material.button.MaterialButton />
    <com.google.android.material.button.MaterialButton />
</com.google.android.material.button.MaterialButtonToggleGroup>

Using TabLayout for tabs gives you a better screen reader result. It now reads that those views are tabs, how many of them the TabLayout has and which one is selected:

<com.google.android.material.tabs.TabLayout />

Do Not Use the Standard Toolbar, ActionBar or ActionMode

The Android Toolbar is not accessible while using a keyboard for navigation. This is a huge issue and may cause you headaches if you try to improve it. Use custom views whenever you feel that you are doing custom work. Custom views are generally more flexible in terms of a11y changes.

Example of a simple custom Toolbar view that can fully replace the standard Toolbar:

<androidx.constraintlayout.widget.ConstraintLayout >
   
   <com.google.android.material.button.MaterialButton />
   
   <TextView
       android:accessibilityHeading="true"
       tools:text="Toolbar title" />
   
   <com.google.android.material.button.MaterialButton />
</androidx.constraintlayout.widget.ConstraintLayout>

Do Not Disable or Hide Buttons on a Screen Based on Some Conditions

Some users (especially those with cognitive impairment) would not know what has to be done in order to enable the given button.

Have the button enabled at all times and display an error after the user clicks on it. Use your current validation for displaying errors rather than disabling/hiding buttons.

Do Not Validate Several Fields at Once on the Fly

This would lead to a long announcement of errors while switching views one by one.

Use Zero-width Space

Zero-width space is encoded as &#xfeff; and allows any screen reader to pronounce your label correctly, regardless of design.

The following string is spoken as 'My Vault':

<string name="title">My&#xfeff;Vault</string>

But this following string is spoken as 'Mevault':

<string name="title">MyVault</string>

Override Accessibility Class for Custom Views

What I learned while working on creating accessible apps was to use custom views instead of trying to bend common ones that are not accessible. It is easier to change them to make them accessible and further work may also be easier, as they are way more customizable.

AccessibilityDelegateCompat

This is a pretty handy method that can be overridden in your custom views. Whenever you create a custom view that should mimic some view, e.g., a custom Checkbox, Switch or Button, you can cheat a little bit and tell TalkBack what the class of the given view should be.

Custom Button view class:

ViewCompat.setAccessibilityDelegate(
   this,
   object : AccessibilityDelegateCompat() {
       override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfoCompat) {
           super.onInitializeAccessibilityNodeInfo(host, info)
           info.className = Button::class.java.name
       }
   }
)

That way, TalkBack says: "Button, Open Settings. Double-tap to activate." instead of "Open Settings. Double-tap to activate.".

Have Confirm Password Input

It’s a good habit to have a Confirm Password input view where the user has to retype a password. This could save you and your users a lot of time when accidentally typing in a wrong password without noticing.

And That’s All From Android

We hope we’ve helped a few people get oriented in the world of digital a11y. While this article marks the end of our four-part Android series, there will no doubt be more coming from other STRV teams — so stay on the lookout. And thank you for reading!

Share this article