09 May 2019
Exposing “hidden” actions to accessibility services used to require providing a custom AccessibilityDelegate
or using a third-party library like Novoda’s accessibilitools.
No longer! There’s a new API dropping in the latest version of AppCompat (1.1.0) which includes a handy way to serve this information to the system with minimum effort.
The function adds additional information to a view which can be read by Android accessibility services. It associates a view with an “action”, where an action consists of a label and executable block of code.
Accessibility services, like TalkBack, can present these actions to users in a way that’s familiar to them. The GIF shows two actions, “watch” and “download”, which have been associated with a view, and how a user can access them with TalkBack:
Use ViewCompat
to set an action on a view, passing the label for the action, and the action to perform:
val watchLabel = getString(R.string.action_watch)
ViewCompat.addAccessibilityAction(itemView, watchLabel) { _, _ ->
onWatchClicked()
}
We’ll repeat this for each action we need to associate:
val downloadLabel = getString(R.string.action_download)
ViewCompat.addAccessibilityAction(itemView, downloadLabel) { _, _ ->
onDownloadClicked()
}
And that’s it! The itemView
now has two actions, “watch” and “download”, which are available to accessibility services like TalkBack.
It works using an AccessibilityDelegate
under the hood to add actions to AccessibilityNodeInfo
. It uses view tags which allows it to add actions over multiple calls without passing them all at once, but we’re limited to 32 actions per view, which is more than enough for a single view.
This is useful when we have actions on a view that aren’t accessible with a simple click—e.g. a swipe-to-delete gesture.
See the “Single-action elements” section in “What’s Next? A Practical Introduction to Accessibility on Android” for more ideas on when this might be useful.
If you have any questions, comments or corrections, let me know!