Michal Urbanek5 min

Accessibility at STRV: Android Common Topics, Pt. 1

EngineeringOct 3, 2021

Engineering

/

Oct 3, 2021

Michal UrbanekAndroid Engineer

Share this article

In our introductory article to Digital Accessibility (a11y), we go over the basics of what accessibility means, why it matters and why it’s a must-have for STRV products. We then dive into the Basics & Tools of Accessibility in Android Apps in part one of our four-part Accessibility in Android Apps article series.

In this second article of the series, our Android team covers a variety of common issues and how you can identify and solve them by properly using specific tools.

Orientation

In WCAG 2.1, a new requirement was added stating that orientation of a piece of content should not be restricted to a single orientation mode (such as portrait or landscape) unless a specific display orientation is essential. As we know, unlocking orientation may be a huge issue, especially when the app is not developed with that set of mind from the very beginning.

This is crucial for users that cannot rotate their screens. One example for all are mounted devices (usually tablets mounted on a wheelchair). We won’t go into detail for this issue in this article, as it is rather self-explanatory.

Color Contrast

A very common issue with high severity is contrast. You can use the Accessibility Scanner to easily discover any contrast issues in your app; it automatically tells you if any view has insufficient color contrast. By default, the scanner looks for AA conformance levels, which means that the given contrast (foreground to background) has to have a ratio of at least 4.5:1.

With contrast, we may be limited by app branding where specific colors have to be used, but we should try to aim at least at AA.

How to Identify:

Use any online Contrast Checker tool or the Accessibility Scanner to discover insufficient contrast.

The Accessibility Scanner tells us that the ratio is only 4.23:1 and thus this is not even AA compliant.

How to Fix:

As the primary step, you should ask your designer to provide you with a new color that would meet this requirement. But, in case you are not working with a designer, you can still use the Contrast Checker tool to find colors with sufficient contrast. You can find your desired color simply by using the Lightness slider.

Useful Tools:

  • Contrast Checker - check the color contrast compliance
  • Color Blender - find a color between two given colors (e.g., between Title and Body text colors)

Content Description

UI elements should be labeled with a proper description that explains a given view’s purpose and what it does. This is primarily important for users that use a screen reader and rely on content labels.

Everyone knows that even Android Studio does not like ImageView without contentDescription property and tells you to handle it.

How to Identify:

Use Android Lint or Accessibility Scanner to discover missing content descriptions. Listen to TalkBack to notice any missing descriptions.

How to Fix Static Assets:

For many images in the app that only have design meaning, we can solve this by setting this property: android:importantForAccessibility="no"

But be careful with images that should communicate something to the user (like infographics, article images, graphs, etc.). As soon as an image has a meaning, it should have a proper description as well. The same goes for IconButtons or even ImageViews that are used as buttons. It’s highly recommended to use MaterialButton, which is prepared for this and its style can be set to any Icon variant, e.g., parent="Widget.MaterialComponents.Button.TextButton.Icon" Those definitively need a content description: android:contentDescription="Description of given view"

How to Fix Dynamic Assets:

There will also definitely be places in your app where you have to add a dynamic content description from code based on some condition. One example could be a button in a list's item placed in RecyclerView that should open a detail screen. You would normally start with android:contentDescription="Open detail", but then all buttons in the list would have the same description. What you should really do in this case is dynamically add a description that would say something like "Open detail of item XYZ"

Set a hint to editable views (EditText) that also represents the field's description: android:hint="User name"

In our custom view where an icon can be changed, the content description has to be changed as well.

fun setIcon(@DrawableRes icon: Int, iconDescription: String) {
	viewIcon.setIconResource(icon)
	viewIcon.contentDescription = iconDescription
}

Touch Target Size

The minimum touch size of any clickable view should always be 48 x 48 dp. This is mandatory for being compliant with a11y guidelines.

How to Identify:

Use the Accessibility Scanner to discover clickable elements with a small target size.

How to Fix:

Increase the target touch area by increasing the size of a view or by using padding or inset.

<item name="android:insetTop">8dp</item>
<item name="android:insetRight">8dp</item>
<item name="android:insetBottom">8dp</item>
<item name="android:insetLeft">8dp</item>

Keyboard Navigation

The main goal is to have the whole app navigable just by using a keyboard. There could be some issues in your app where there may be focus traps (you cannot move from a certain part of the app) or some views or control items cannot be accessed by a keyboard at all. Another part of keyboard navigation is focus; it should be clear at all times where the user is currently navigated by highlighting views (in our case, by focusing views).

There are problematic widgets in Android which you may be using. The most common and problematic views are the standard Toolbar and ActionBar (go ahead and try to navigate to any Menu icon in your Toolbar). Action Mode for selection can be even worse. These views are not accessible at all at this moment and could give you a serious headache while trying to improve them.

Replacing those problematic views with different or custom ones may fix the issue. Sometimes, the view may not be set as focusable or  property descendantFocusability is used for the parent view, which may be stealing the focus. When you are not able to navigate to a view just by using arrows on a keyboard and you cannot find any working solution, try to navigate to your view with a combination of arrows and tab keys — that way, the issue can be marked as partially fixed.

Navigation Focus

Always make sure your focus is visible while navigating on the screen, especially when using custom views or overriding color for your widgets. Focus visibility is required in order to see where the user is currently navigated on the screen.

Focus can be broken due to several issues or a combination of them. This could be fixed by specifying state_focused property in your color selector, stopping the overriding background color or adding rippleColor property.

Example of setting rippleColor in style of a button:

<style name="Widget.A11Y.Button"
	parent="Widget.MaterialComponents.Button.UnelevatedButton">
	<item name="rippleColor">@color/ripple_color</item>
	...
</style>

Example of setting ripple as a part of a shape drawable:

<ripple
   android:color="@color/ripple">

   <item>
       <shape android:shape="rectangle">
           <solid android:color="@color/button_color" />
           <corners android:radius="12dp" />
       </shape>
   </item>
</ripple>

Example of setting state_focused property in color selector:

<selector>
    <item android:state_focused="true"
        android:color="@color/focused_color" />
</selector>

Next UP: Android Common Topics, Pt. 2

In the coming weeks, we’ll be publishing Accessibility at STRV: Android Common Topics, Pt. 2 and Best Practices.

We hope these articles will help inspire a greater focus on accessibility in our industry, because we’re convinced inclusivity on all levels is a must-have.

Share this article