# Accessibility in Android: STRV Common Topics Pt. 2

[Michal Urbanek](https://www.strv.com/blog/authors/michal-urbanek)  
Android Engineer

---

## Introduction
As promised, we’re back with more digital accessibility (a11y) content. For those catching up, we recommend checking out our [Intro to Digital Accessibility](https://www.strv.com/blog/what-is-accessibility-why-its-a-must-have-at-strv-product?ref=strv.ghost.io), [the Basics & Tools of Accessibility in Android Apps](https://www.strv.com/blog/accessibility-at-strv-android-basics-best-tools-engineering?ref=strv.ghost.io), and [Android Common Topics, Pt. 1](https://www.strv.com/blog/accessibility-at-strv-android-common-topics-pt-1-engineering?ref=strv.ghost.io).

We’ve gone over a lot of issues that can be revealed mainly by Android Scanner or by using a keyboard for navigation. Now, with this article (the third of our four-part Android series), we’d like to continue with a11y issues that can be recognized by a screen reader — in our case, TalkBack.

---

## State Announcement
Basically, you can (and should) announce everything that happens on the screen. Here are some things that should be announced by TalkBack:

### Entering a Screen
This is something taken from a Google Play app where they announce that the detail of an app was opened. The easiest way would be to announce the Toolbar title since it would be sufficient information in most cases. You may sometimes need more information, e.g., when you open Profile Detail; you can then add a user name and make the announcement dynamic.

Example with SettingsFragment.kt:
```kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    requireView().announceForAccessibility("Settings")
}
```

### Progress States
There may be cases where you show a progress bar while sending an event to the server and waiting for a response. This is pretty straightforward for users who can see what is happening on the screen, but users using TalkBack would not have any idea about the current state.

Display and announce the loading state while fetching records from the server:
```kotlin
buttonApply.setOnClickListener {
    progressView.visibility = View.VISIBLE
    progressView.announceForAccessibility("Loading more records")
    ...
    progressView.visibility = View.GONE
    progressView.announceForAccessibility("More records loaded")
}
```

### Error States
The best thing would be not to use any custom errors but rather errors that are a part of the TextInputLayout view or similar views. In the real world, we do need to show a custom error from time to time. When doing this, we must also announce this error via TalkBack.

A common mistake is using Toast or Snackbar views for errors, which breaks WCAG requirements — users should have enough time to read the content. These self-dismissable views are not compliant for such information.

Here’s an example of a custom Button view capable of displaying an error. You can manually announce the error with `announceForAccessibility` or use `sendAccessibilityEvent` with event `TYPE_VIEW_ACCESSIBILITY_FOCUSED` to ensure it is spoken by the screen reader:
```kotlin
fun setError(errorText: String) {
    errorTextView.text = errorText
    errorTextView.visibility = View.VISIBLE
    errorTextView.sendAccessibilityEvent(
        AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
    )
}
```

### Selections
When any selection happens, it should be communicated to the user. For example, selecting a date in a calendar picker can be announced once the user clicks on the Select button.

In a dialog where an option is selected and value passed to the parent:
```kotlin
buttonOptionOne.setOnClickListener { button ->
    button.announceForAccessibility("Option 1 selected.")
    dismiss()
}
```

### Other Screen States or Actions
Other actions that should be announced include delete, update, or create of a record:
```kotlin
buttonDeleteRecord.setOnClickListener { button ->
    button.announceForAccessibility("Record deleted.")
    finish()
}
```

---

## Screen Order
While using a screen reader, users may not be aware of disclaimers located below actionable items.  

For example, a disclaimer placed below a Submit button might not be read if the user navigates directly to the button first; the disclaimer could be skipped before pressing Submit.

---

## Grouping Views Together
Some views don’t make sense when read alone by TalkBack, e.g., a TextView "Start date" and another with the actual date, or a Profile item with Photo, UserName, and Email. List items inside RecyclerView can also benefit from being grouped.

To do this, put views into a ViewGroup and make it focusable: `android:focusable="true"`. This way, TalkBack treats the entire group as one unit, reading its description collectively, making much more sense.

For API level 28+:
Use `android:screenReaderFocusable="true"` on the ViewGroup and set children to `android:focusable="false"`.

Example:
```xml
<LinearLayout
    android:focusable="true">
    <TextView android:text="Start date" />
    <TextView android:text="10/10/2021" />
</LinearLayout>
```
This grouping results in better reading, e.g., “Start date Saturday May first.”

---

## Headings
TalkBack can jump through all headings on a screen. To make titles or subtitles more accessible, add: `android:accessibilityHeading="true"` in your layout.

For example, setting a TextView as a heading:
```xml
<TextView
    android:text="Important Title"
    android:accessibilityHeading="true" />
```

Using headings for section titles or toolbar titles helps navigation.

---

## Labels and Live Region
You can pair views with `android:labelFor="@+id/slider"` to describe them, e.g., a slider with a TextView showing its value.

A useful property for dynamic updates is `android:accessibilityLiveRegion="polite"`, which notifies users of view changes automatically.

---

## Read Order
The read order of views can be customized with:
- `android:accessibilityTraversalBefore="@id/xyz"`
- `android:accessibilityTraversalAfter="@id/xyz"`

By default, views are read from top to bottom, but in some cases, you might want to adjust the order, especially if it differs from visual layout.

---

## Don't miss anything