0% found this document useful (0 votes)
322 views217 pages

Android Accessibility by Tutorials-Razeware LLC. (2022)

Uploaded by

Julio Cesar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
322 views217 pages

Android Accessibility by Tutorials-Razeware LLC. (2022)

Uploaded by

Julio Cesar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 217

Android Accessibility by Tutorials Android Accessibility by Tutorials

Android Accessibility by Tutorials


Victoria Gonda

Copyright ©2022 Razeware LLC.

Notice of Rights
All rights reserved. No part of this book or corresponding materials (such as text,
images, or source code) may be reproduced or distributed by any means without
prior written permission of the copyright owner.

Notice of Liability
This book and all corresponding materials (such as source code) are provided on an
“as is” basis, without warranty of any kind, express of implied, including but not
limited to the warranties of merchantability, fitness for a particular purpose, and
noninfringement. In no event shall the authors or copyright holders be liable for any
claim, damages or other liability, whether in action of contract, tort or otherwise,
arising from, out of or in connection with the software or the use of other dealing in
the software.

Trademarks
All trademarks and registered trademarks appearing in this book are the property of
their own respective owners.

raywenderlich.com 2
Android Accessibility by Tutorials

Table of Contents: Overview


Book License ................................................................................................ 8
Before You Begin ................................................................... 9
What You Need ........................................................................................ 10
Book Source Code & Forums ............................................................. 11
Section I: Android Accessibility by Tutorials ............. 15
Chapter 1: Why Accessibility ................................................. 16
Chapter 2: Hello, Accessibility! ............................................. 30
Chapter 3: Testing & Tools ...................................................... 48
Chapter 4: Perceivable — Layout & Labeling ................... 68
Chapter 5: Perceivable — Time-Based Media & Cues . 86
Chapter 6: Perceivable — Colors ....................................... 101
Chapter 7: Operable — Navigating the Screen ............ 117
Chapter 8: Operable — Movement & Timing ................ 141
Chapter 9: Understandable ................................................. 154
Chapter 10: Robust ................................................................. 176
Chapter 11: Designing for Neurodiversity .................... 190
Chapter 12: Getting Your Team on Board ...................... 203
Conclusion .............................................................................................. 212
Section II: Appendix ........................................................ 214
Appendix A: Accessibility Checklist ................................. 215

raywenderlich.com 3
Android Accessibility by Tutorials

Table of Contents: Extended


Book License . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Before You Begin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
What You Need . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Book Source Code & Forums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
About the Editors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

Section I: Android Accessibility by Tutorials . . . . . . . 15


Chapter 1: Why Accessibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Caring About Accessibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Experiencing Your App. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Key Points. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Where to go from here?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Chapter 2: Hello, Accessibility! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Introducing Taco Tuesday . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Improving Accessibility Through Linters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Defining WCAG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Choosing Universal Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Key Points. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Where to Go From Here? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Chapter 3: Testing & Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Setting Up Your Device . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Using Accessibility Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Testing for Accessibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Knowing How Much To Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Key Points. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

raywenderlich.com 4
Android Accessibility by Tutorials

Chapter 4: Perceivable — Layout & Labeling . . . . . . . . . . . . . . . . 68


Defining Perceivable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Understanding Screen Readers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Including Effective Text Alternatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Hiding Decorative Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Writing Clear Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Creating Adaptable Layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Supporting Text Scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Key Points. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Where to Go From Here? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Chapter 5: Perceivable — Time-Based Media & Cues . . . . . . . 86
Displaying Time-Based Media . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Giving Cues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Key Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Where to Go From Here?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Chapter 6: Perceivable — Colors . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Measuring Color Contrast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Understanding Vision Impairments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
Improving Color Contrast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Introducing Dark Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Key Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Where to Go From Here?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Chapter 7: Operable — Navigating the Screen . . . . . . . . . . . . . 117
Traversing Using a Keyboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Navigating Your App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Considering Touch Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Key Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Chapter 8: Operable — Movement & Timing . . . . . . . . . . . . . . . 141
Considering Adjustable Timing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142

raywenderlich.com 5
Android Accessibility by Tutorials

Giving Auto-Update Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144


Managing Interruptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Identifying Time Limits in Your App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Mitigating the Risk of Adverse Reactions . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Key Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Where to Go From Here?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Chapter 9: Understandable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Increasing Readability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Creating Predictability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Key Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Chapter 10: Robust . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
Relying on System Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Indicating a View’s Role . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Building Custom Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
Seeing Service Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Key Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Chapter 11: Designing for Neurodiversity . . . . . . . . . . . . . . . . . 190
Reducing Time Stress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Communicating with Clarity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Providing Help. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
Achieving Consistency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
Minding Your Phrasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
Giving Alternatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Supporting Configurability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
Key Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Where to Go From Here?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Chapter 12: Getting Your Team on Board . . . . . . . . . . . . . . . . . . 203
Recognizing a Need . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
Getting Buy-In . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204

raywenderlich.com 6
Android Accessibility by Tutorials

Expecting Pushback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207


Scaling Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Tracking Improvement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
Key Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Where to Go From Here?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
Section II: Appendix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Appendix A: Accessibility Checklist . . . . . . . . . . . . . . . . . . . . . . . . 215
Quick Peek Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
Thorough Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216

raywenderlich.com 7
L Book License

By purchasing Android Accessibility by Tutorials, you have the following license:

• You are allowed to use and/or modify the source code in Android Accessibility by
Tutorials in as many apps as you want, with no attribution required.

• You are allowed to use and/or modify all art, images and designs that are included
in Android Accessibility by Tutorials in as many apps as you want, but must include
this attribution line somewhere inside your app: “Artwork/images/designs: from
Android Accessibility by Tutorials, available at www.raywenderlich.com”.

• The source code included in Android Accessibility by Tutorials is for your personal
use only. You are NOT allowed to distribute or sell the source code in Android
Accessibility by Tutorials without prior authorization.

• This book is for your personal use only. You are NOT allowed to reproduce or
transmit any part of this book by any means, electronic or mechanical, including
photocopying, recording, etc. without previous authorization. You may not sell
digital versions of this book or distribute them to friends, coworkers or students
without prior authorization. They need to purchase their own copies.

All materials provided with this book are provided on an “as is” basis, without
warranty of any kind, express or implied, including but not limited to the warranties
of merchantability, fitness for a particular purpose and noninfringement. In no event
shall the authors or copyright holders be liable for any claim, damages or other
liability, whether in an action of contract, tort or otherwise, arising from, out of or in
connection with the software or the use or other dealings in the software.

All trademarks and registered trademarks appearing in this guide are the properties
of their respective owners.

raywenderlich.com 8
Before You Begin

This section tells you a few things you need to know before you get started, such as
what you’ll need for hardware and software, where to find the project files for this
book, and more.

raywenderlich.com 9
i What You Need

To follow along with this book, you’ll need the following:

• An Android device: While it is possible to follow along using an emulator,


emulators don’t support all accessibility features and the features they do support
can be challenging to use.

• Kotlin 1.6 or later: This book uses Kotlin 1.6 throughout. The examples may work
with an earlier version of Kotlin, but they are untested.

• Android Studio Chipmunk or later: Android Studio is the main development


tool for Android. You’ll need Android Studio Chipmunk or later for the tasks in this
book. You can download the latest version of Android Studio from Android’s
developer site here: https://developer.android.com/studio.

If you haven’t installed the latest version of Android Studio, be sure to do that before
continuing with the book. The code covered in this book depends on Android 12,
Kotlin 1.6 and Android Studio Chipmunk — you may get lost if you try to work with
an older version.

raywenderlich.com 10
ii Book Source Code &
Forums

Where to Download the Materials for This


Book
The materials for this book can be cloned or downloaded from the GitHub book
materials repository:

• https://github.com/raywenderlich/acca-materials/tree/editions/2.0

Forums
We’ve also set up an official forum for the book at https://
forums.raywenderlich.com/c/books/android-accessibility-by-tutorials. This is a great
place to ask questions about the book or to submit any errors you may find.

raywenderlich.com 11
”It’s the support of many people that made this book possible.
My computer science professors first showed me what I could
do to help people through software. My peers supported me as
I learned more about tech, accessibility, and writing. The
editing team on this book has been incredible in building this
together. Finally, I couldn’t have done this without the
support of my husband, Tyler, encouraging me every step of
the way. Thank you, all.”

— Victoria Gonda

raywenderlich.com 12
Android Accessibility by Tutorials About the Team

About the Author


Victoria Gonda is the author of this book. They are a software
engineer who primarily works with Android. After having studied
both dance production and computer science, they focused their
career on software because of its potential to help people in a
meaningful way. This is visible in their passion for accessibility. In
their spare time, Victoria enjoys playing board games and curling
up with a good book. You can connect with them on Twitter at
@TTGonda.

About the Editors


Gabriela Kordić is the tech editor of this book. She is a tech
enthusiast with a master’s degree in Computer Science based in
Osijek, Croatia. She got into programming during college and has
been developing Android and iOS apps for several years. Her
passion for sharing knowledge drives her to contribute to the
developer community through books and tutorials. In her spare
time, Gabriela attends tech talks and invests time in learning new
things from the programming world. When she’s not crushing it in
the tech world, she enjoys spending time with her husband and cat,
going into the forest with her horse and playing the piano.

Ellen Shapiro is an iOS and Android developer currently working


at Gusto. She helped bring songwriting app Hum to life, worked
extensively on the Apollo GraphQL iOS SDK, and has been a writer
and tech editor for RayWenderlich.com and its associated books
since 2013. She’s also developed several independent applications
through her personal company, Designated Nerd Software. When
she’s not writing code, she’s usually tweeting about it at
@DesignatedNerd, playing sous-chef to her wife Lilia, or
relentlessly Instagramming her two cats.

raywenderlich.com 13
Android Accessibility by Tutorials About the Team

Jennifer Bailey is a former software engineer who is now a full-


time professor for Aims Community College in Colorado where she
teaches mobile app development for Android and iOS. She also
teaches courses in Python, Java, C++, and .NET platform utilizing
C#. She is the lead organizer of Google Developer Group of
Northern Colorado. She enjoys various Android meetups and
conferences around the United States. In her spare time, Jenn
enjoys rollerblading, horseback riding and spending time with her
teenage daughter, dogs and cats.

raywenderlich.com 14
Section I: Android
Accessibility by Tutorials

Begin your journey into learning about building, testing and customizing accessible
apps on Android using WCAG through hands-on, step-by-step tutorials.

raywenderlich.com 15
1 Chapter 1: Why
Accessibility
By Victoria Gonda

Thank you! By picking up this book, you’re proving that you care about an important
topic: accessibility, which is often shortened to a11y. Whether you’re looking to
deepen your existing accessibility knowledge, or are beginning your learning
journey, this book will support your goals.

In this first chapter, you’ll discover what accessibility is and answer the question:
Why should I care about accessibility? Once you reach the end of this chapter, you’ll
have several answers to that question, and you’ll be able to have effective
conversations with your peers about why developers should prioritize accessibility in
their designs.

Caring About Accessibility


Imagine: You’re stuck at home and need something to eat. You can’t leave because
you broke your hand, your car is in the shop, and you have a sweet, new puppy that
will destroy everything if you turn your back for too long.

And now you’re hungry. You’ve got an insatiable craving for a burrito, and you decide
to try a burrito-ordering app a friend recommended. As your hunger grows, so does
your frustration. You can’t place an order because your broken hand is making it
difficult to use your phone. Additionally, you don’t know which buttons do what.

Something is missing from the form, but the app doesn’t say what. You desperately
need some guacamole on this burrito, and you can see the “add guacamole” option
but can’t select it.

raywenderlich.com 16
Android Accessibility by Tutorials Chapter 1: Why Accessibility

How would you feel? A little hangry? Is it your right to order that burrito? What’s
your perception of this food delivery app?

Keep those thoughts in mind as you keep reading.

An accessible app means that most people can use it without help from another
person, regardless of ability or situation. When there’s a mismatch between the app
and the users’ abilities, an app is considered inaccessible.

Inaccessible apps put barriers between a user and the task they are trying to
do.

You can see ways physical objects are accessible, be it ramps in front of buildings or
braille on the elevator buttons. But what does accessibility mean for digital objects,
specifically, your apps? And why should you care?

This chapter focuses on that second question, and the rest of the book is dedicated to
the first.

There are many reasons to care, including those below—in no particular order. By
developing an accessible app you:

• Open your app to a wider audience.

• Minimize risk of legal battles.

• Make a better product.

• Drive innovation.

• Increase developer productivity.

• Recognize revenue potential.

• Treat others with care.

raywenderlich.com 17
Android Accessibility by Tutorials Chapter 1: Why Accessibility

Widening Your Audience


According to the Centers for Disease Control and Prevention (CDC), 1 in 4 adults
in the United States has a disability (https://www.cdc.gov/media/releases/2018/
p0816-disability.html).

1 in 4 adults in the United States has some type of disability.


When you scale that number to the entire world, that’s a huge potential audience to
whom you can open your app simply by making it accessible. Conversely, if your
competition’s app is accessible but yours is not, you’re essentially capitulating on
market share.

Note: Does that number surprise you? Keep in mind two points:

1. Many people have invisible disabilities. You could know someone your
whole life and never know they have dyslexia and struggle to read. The young
mom you walk past in the grocery store may have a perfect, happy-go-lucky
face but you don’t know that she’s in chronic pain from a disease that destroys
her ligaments and muscles.

2. Different communities have different concentrations of people with


disabilities. For example, “2 in 5 adults age 65 years and older have a
disability” according to the CDC.

Learn more about disabilities among different groups at https://www.cdc.gov/


ncbddd/disabilityandhealth/infographic-disability-impacts-all.html.

raywenderlich.com 18
Android Accessibility by Tutorials Chapter 1: Why Accessibility

Avoiding Assumptions
As a developer, it’s a force of habit to assume what people will and won’t do with
your app. Maybe you think: “I’m building a fitness app. People with motor
disabilities aren’t using my app” or “I have a parking app. Why would anybody with
vision impairment think to use it?”

You should not make assumptions about what people can do or the value they get
from your app. Every single person has their own story and way of interacting with
the world.

Maybe that user with vision impairments books parking spaces for a friend, who’s
coming to visit soon. Or that user with motor impairments is helping their cousin
train for a triathlon with your fitness app.

There are a million possibilities. You can’t assume you know them all. In addition,
you can’t assume that everyone who has a disability with the same name has the
same abilities. Disabilities manifest themselves in diverse ways with different
people.

If you think that two people with hearing disabilities will experience your app the
same way, you’ll be wrong.

Avoiding Legal Battles


Did the words “legal battles” get your attention? That’s right, it’s the law that your
app be accessible. It’s a civil right. People with disabilities must have access to public
accommodations and commercial facilities.

Because of laws such as the Americans with Disabilities Act (or ADA) in the United
States and the Web Accessibility Directive (or WAD) in the European Union, it’s
prohibited to discriminate based on disabilities.

Here’s a powerful example of why you should care about accessibility: Guillermo
Robles wanted to order from Domino’s Pizza. More than once, Robles used the
Domino’s Pizza app to place an order only to discover he could not.

See, Robles is blind and uses assistive technologies, but the app did not support the
correct technologies. He brought his concerns to court and won in the case Robles v.
Domino’s Pizza (https://law.justia.com/cases/federal/appellate-courts/
ca9/17-55504/17-55504-2019-01-15.html).

raywenderlich.com 19
Android Accessibility by Tutorials Chapter 1: Why Accessibility

Back to your app: Someone can sue you for creating an inaccessible app if you
market your app in any country that has these protections if you don’t follow
accessibility guidelines. That sounds scary—and expensive!

It’s a good thing that you’ll learn about those guidelines in this book so you can
avoid that. Surely, Domino’s wishes it had your foresight.

Making a Better Product


Have you ever used voice control to perform a task on your phone while you were
responsibly driving with both hands on the wheel? Is your phone on vibrate so you
can feel when you get a message rather than hear it? Perhaps you use captions when
watching a video in a noisy location, or if you’re an American trying to understand
the strong Northern Irish accents in Derry Girls.

Have these functions caused you to enjoy the apps on your device more than you
might have otherwise? All these actions are supported by accessibility features.

Stop and think: What everyday features do you use, either in the physical or
digital world, that could be an accessibility feature? Hint: Many things have
multiple ways to consume information or perform a task, which improves their
accessibility.

Supporting accessible features makes for a more enjoyable experience for all of your
users. Not only does it manifest itself in the ways described above, but it also makes
your app more consistent and easier to use, which increases users’ happiness and
engagement.

Accessibility can be the difference between a one-star and five-star review.

One-star play store review next to a five-star review.


Supporting accessibility also benefits you, the developer, by opening up
opportunities for your app.

raywenderlich.com 20
Android Accessibility by Tutorials Chapter 1: Why Accessibility

For example, when you integrate with the device system in a way that makes your
app accessible, it means that if you port your app to a TV platform, you’ll be able to
navigate it with a remote. In the case where you enable your app for Android Auto,
the app can be used via voice. When users attach a keyboard to their tablet, they’ll be
able to navigate that form you have in your app using the keyboard. Who really wants
to move the mouse or tap the screen to move to the next field when you can press
tab?

Driving Innovation
Designing with accessibility in mind encourages you to make a better product and
can drive innovation. Scholars have studied and discovered that by placing limits on
a project, you foster greater creativity. After all, an app that does EVERYTHING is a
poorly designed product.

So, maybe you can’t fit everything you want onto a certain screen because the view
needs to be large enough to interact with and consume. This means you need to get
creative and really think about what content you need where.

You get to come up with fresh new ways to communicate to your users what you
mean, and you are required to think hard about how to make your app simple and
easy to use.

These constraints may feel like a burdensome creative writing assignment, but the
limitations will improve your creative processes when you design apps!

Stop and think: Pick a screen in one of your favorite apps. Now pick a
constraint and think about how you might change the screen. Maybe the
constraint is that you can only have half the content on the screen, or that
everything needs to be 2x bigger. Some other options might be you can only
use black and white, or there are no images allowed.

How would you redesign the screen to meet these requirements?

See how constraints can spark your creativity?

Increasing Developer Productivity


Surprised? How can something that will require a lot of your time increase your
productivity? Simple: Building an accessible app encourages the use of reusable
components and a design system.

raywenderlich.com 21
Android Accessibility by Tutorials Chapter 1: Why Accessibility

Because you’re doing the same thing multiple places in the app, you, as the “lazy
developer” will find a way to do it once and abstract it away. And surely, your
designers will welcome an established design system.

This is great news for you too! You’ll have plug-and-play components that allow you
to build new features at lightning speed. The gains you would have made by ignoring
accessibility may help you in the short term, but supporting accessibility will help
you in the long term.

While maintaining an accessible app, you’ll also find that it encourages and supports
conducting UI tests in your app. Espresso tests on Android even hook into
accessibility services and Jetpack Compose tests use the same nodes that
accessibility services get information from! You’ll learn more soon about how UI
tests support your quest for a more accessible app.

One of the biggest themes you’ll learn in this book, on top of how to make your
Android app accessible, is how designing with accessibility in mind can improve your
product and engineering practices, justifying your upfront investment.

Recognizing Revenue Potential


Neglecting accessibility in your apps could mean that you lose revenue.

Right here, right now is your chance to change your thinking from “We don’t have
the resources to think about accessibility” to “We don’t have the resources to NOT
think about accessibility.”

There were hints that neglecting accessibility can cause you to lose money above.
For example, by supporting accessibility in your apps, you’re minimizing the risk of
incurring legal fees and liability due to non-compliance.

How else might accessibility affect your profitability?

You’ve already read that having an accessible app makes for a better product.
Following the guidelines makes it possible for people with disabilities to use your
app and enables more users to have better experiences with your app. When your
app delights people, they’re more likely to rate it highly and tell their friends about
it.

If your app is inaccessible, you won’t experience these benefits.

Imagine a person named Tyler downloads the trial version and then discovers he
can’t use your app. That’s one less paying customer.

raywenderlich.com 22
Android Accessibility by Tutorials Chapter 1: Why Accessibility

But wait — it’s not only him. You’re also losing every single referral he would have
given if he had a better experience. You lose the people who see his one-star review
and decide not to download your app.

Then, those people who decided not to use your app, never get to refer their friends
to it. This branching can grow exponentially.

What about the people who can use your app? Imagine someone named Laura, for
example, who isn’t disabled but struggles to remember how to use apps. They use
your app but feel discontent with it.

They might continue to use it but will not recommend it to others. They are already
trying out competitors’ apps to find one that gives them a better experience and has
complained about your app to their friends.

By leaving someone out, you also lose their potential advocacy.


You want your app to be a success. You can’t afford to let your users down with an
inaccessible design.

Treating Others With Care


Even if all that wasn’t enough reason to care, there’s one more: People with
disabilities deserve to have access to the same services everyone does. This includes
your app. Plainly said: Supporting an accessible app is the right thing to do.

Society has normalized accessibility in the physical world with affordances like
dedicated parking spaces and wheelchair-accessible layouts in grocery stores. Now
that so many companies exist online, the tech sector needs to consider accessible
user experiences as a key requirement for all user experiences.

When you market an inaccessible app, you send the message to some people that
“We don’t want you here”. You may not realize you’re acting in a hurtful way, but
that doesn’t mean that your insensitivity doesn’t hurt.

raywenderlich.com 23
Android Accessibility by Tutorials Chapter 1: Why Accessibility

Let’s change the narrative “Heroic disabled person overcomes obstacles” to


“Society is inclusive, all can succeed.”

-Haben Girma

In the end, you should build quality apps because you care about having a quality
app that can reach the biggest audience possible. And build accessible apps that
demonstrate the care that you want to see in the world.

You now understand why you should care about making your app accessible to
everyone, regardless of how they perceive or operate it. To help you wrap your head
around what that might look like, you need to know about some of the different
situations that cause people to experience your app differently.

Experiencing Your App


The first thing you need to recognize is that temporary, partial and permanent
disabilities all change the way people experience your app.

Someone might struggle to see what’s on-screen because they have color-blindness
or because it’s bright outside. They might have a hard time performing a gesture
because they have tremors or because they broke their hand. They might not hear
the content of your video due to hearing loss or because they are in a noisy place.

These people often use assistive technologies to allow them to consume your app in
a way that makes sense for them.

Accessible design improves your app for so many people in all kinds of situations.

There are four different categories where the user’s ability can change the way they
experience your app:

1. Visual.

2. Motor.

3. Auditory.

4. Neurodiversity.

raywenderlich.com 24
Android Accessibility by Tutorials Chapter 1: Why Accessibility

Visual Impairments
There is a wide range of ways people might experience visual limitations, from being
near-sighted or having color blindness, to being legally blind. Other visual
impairments include:

• Tunnel vision.

• Wooly or cottony opacity in the central vision but not necessarily the peripheral
vision.

• Cloudy vision.

• Light sensitivity.

• Double vision.

• Black spots or floating shapes.

• Loss of peripheral vision.

This grid shows a simulation of different vision impairments. These were generated using
the NoCoffee Chrome plugin. Search 'Vision Simulator Chrome plugin' to try it yourself.

raywenderlich.com 25
Android Accessibility by Tutorials Chapter 1: Why Accessibility

Many of these have ranges in themselves, for example, low vision loss to complete
vision loss. Vision loss could be in one or both eyes. It could be temporary, such as
after an injury or after the eye doctor dilates your eyes.

When building apps, you should not make assumptions about what users can and
cannot see, as each user’s visual experience will be unique. You should also keep in
mind that people might be using assistive technologies such as magnification or
screen readers.

Motor Impairments
Motor impairments affect the way people move. Some of the types of motor
disabilities that impact the way someone uses an app include:

• Paralysis in some or all limbs.

• Loss or damage of one or more limbs.

• Low dexterity or poor fine motor skills.

• Pain while moving.

• Slowness.

• Weakness.

• Stiffness.

• Loss of muscle control, which can result in muscle tightness and unpredictable
movements.

• Tremors.

Also consider temporary impairments, such as having a splint on your finger or


restrictions because you’re carrying something heavy.

As you can see, there are many different interactions to consider here when making
your app accessible. In Chapter 3, “Testing & Tools”, you’ll learn about some of the
tools people use to interact with their devices.

Try: Use your phone with your non-dominant hand. This might be frustrating
for you at first. However, you can imagine how living with an impairment
every day would allow you to learn to excel at using accessibility tools to
perform tasks without the dexterity you previously had. You can make using
these tools possible by building an accessible app.

raywenderlich.com 26
Android Accessibility by Tutorials Chapter 1: Why Accessibility

Auditory Impairments
While there are multiple classifications of hearing loss, the most important thing for
you to consider is that some people won’t be able to hear your app. This could be due
to damage to the parts of the ear, nerve damage, a total loss of hearing, loss of
hearing of high or low tones or a loss of hearing in one ear.

Either way, you’ll learn techniques for building apps for users with auditory
impairments.

Try: Spend a whole day, or even a whole week, with all the sound turned off on
your phone. This means no ringer, no alarm, no podcasts and no audio on
videos. In what places might you need to find alternative ways to use your
phone, and what might those alternatives be?

When your apps support the option to consume them in this way, using your
phone without audio can feel natural.

Neurodiversity
Neurodiversity, for the sake of this discussion, comprises the natural differences
people have when it comes to neurological structure and function. Brains are
remarkably complex, so we experience and interact with the world in wildly different
ways.

This is perhaps the broadest category discussed here. While you’re reading these,
keep in mind that there are many ways to experience every one of these.

Memory

Some people may have trouble remembering a piece of information from one task to
the next. They could forget an instruction or what an unlabeled icon does. They
might forget how they reached a specific screen in your app, or forget what to do
once there.

raywenderlich.com 27
Android Accessibility by Tutorials Chapter 1: Why Accessibility

Problem-solving

It’s extremely frustrating to experience a problem and not know how to solve it.
When designing for accessibility, you need to be clear about why a problem occurs
and what the user can do to solve it.

Attention

Keep in mind that distractions may pull users away from your content. You can help
with this by reducing the distractions you provide. Distractions can be as simple as
asking the user to confirm actions repeatedly, not showing a loading bar, or sending
the user to another website for some information.

Reading and language

The text you use in your app is important to the way it’s understood. With that, you
need to know that some people have difficulty reading or comprehending, so try to
reduce complexity. It can also confuse when you use sarcasm and idioms.

Math

Similar to language, some people struggle to understand numbers and math


equations. Be careful how you use them and provide explanations where you can.

Visual comprehension

Of the people who can see images and icons, some will not comprehend what is in
the image or what the icon represents. You can’t assume that all users understand
what a hamburger menu does. It’s helpful to include text, along with the icon or
image, to clarify what the element does.

Anxiety

When you introduce uncertainty, it can trigger anxiety in some users. It helps to be
clear about what will happen when the user performs a given action and not rush
them into performing a task.

By keeping these things in mind, you can make your app much easier and more
enjoyable to use by many people.

raywenderlich.com 28
Android Accessibility by Tutorials Chapter 1: Why Accessibility

Key Points
• To create an accessible app, you must design it so that most people can use it
without assistance.

• Accessible apps widen your audience to the 1 in 4 adults who have some type of
disability.

• You can face legal battles if your app is inaccessible.

• Developing an accessible app makes your product better and increases developer
productivity.

• The constraints of accessibility guidelines will drive innovation.

• You can lose potential revenue if you neglect accessible design.

• Having access to apps is a civil right, and caring about accessibility is the right
thing to do.

• Visual, motor, auditory and cognitive impairments change the way people
experience your app.

Where to go from here?


You now know why you should care about accessibility and understand the different
impairments that impact the way someone may use your app. And now that you
know, you’re prepared to start learning the skills and applying this knowledge!

You won’t render your users burrito-less, anxious or feeling discontent with your
app.

In the next chapter, you’ll get started on fixing up a taco recipe app to make it more
accessible. Because who doesn’t love accessible tacos?

raywenderlich.com 29
2 Chapter 2: Hello,
Accessibility!
By Victoria Gonda

One of the best ways to learn is to jump right in and start applying your new
knowledge. Throughout this book, you’ll be working on making an app more
accessible. You’ll be able to apply the techniques you learn here right away, whether
you’re working on an existing app or building a new one outside of this book. You
don’t even need to finish the book to start applying the new information from each
chapter in your projects!

You’ll soon see that you already have the tools to get started and that it takes only a
couple of lines of code to make a big difference for your users.

Introducing Taco Tuesday


Taco Tuesday is the name of the app you’ll develop as you work through this book.
It allows you to discover and save new recipes to enjoy on your next Taco Tuesday.
Once you’ve found a recipe you like, you can indicate that you made it, rate it and
add notes.

Find the starter project in the materials for this chapter and open it in Android
Studio. Build and run the project.

raywenderlich.com 30
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

You’ll see that there are auto-advancing slides followed by recipe cards at the
onboarding stage. You can swipe the recipe cards to the right and left to save for
later or pass them up, respectively, and move to the next recipe.

On-boarding screenshot next to a discover screenshot.


Tap Favorites to see the saved recipes. To see a details screen that shows all the
ingredients and instructions for a certain recipe, tap the View icon on the recipe
card. From here, you can add your rating and notes if you’ve saved the recipe.

Recipe list screenshot next to a details view screenshot.

raywenderlich.com 31
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

Finally, you’ll see some pop-up dialogs and a bare-bones settings screen.

Screenshot of pop-up next to a screenshot of the settings screen.


You may have noticed the app has several unpleasant features. The pop-ups are
disruptive and the on-boarding process is unclear.

As you improve the app’s accessibility, you’ll also improve the overall user
experience. When you complete this book, the app will look more like this:

Screenshots of final discover, list and details views.


So much nicer! Without further ado, it’s time to dig in and start improving this app!

raywenderlich.com 32
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

Improving Accessibility Through Linters


Do you feel lucky? Well, you are! Not only do you have this book in your hands, but
you probably already use one of the tools that can make your app more accessible:
lint. Android linters include a category that’s all about supporting accessibility.

List of linters in Android Studio.


In most cases, Android Studio enables the lint rules by default. Before you proceed,
though, make sure that they are really enabled by following next steps.

In Android Studio, go to Preferences ‣ Editor ‣ Inspections.

Pick the right profile at the top — there are some options:

• If you choose Project Default, you can check your lint rules into version control.

• Otherwise, if you pick Default, they will be your local rules. You can create more
profiles if needed.

For this project, it doesn’t matter which profile you use, so just pick one.

By default, there are two lint profiles to choose from.

raywenderlich.com 33
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

Review the list of items below the profile selection. Look for Android ‣ Lint ‣
Accessibility. Select the checkbox at the end of each item.

Check each accessibility linter.


On the right side of the Preferences window, you can set the lint severity. Select each
accessibility lint and make sure the severity is Warning or Error.

Warning severity.
Click OK to save the lint settings and close Preferences. Now you’re all set to see
lint errors.

Seeing Lint Errors


You have some options for how to view lint errors. The first way is to use Gradle in
the command line. Run this command if you’re on Linux or Mac:

./gradlew lint

Or this one for Windows:

gradlew lint

Note: You can use the terminal window in Android Studio under View ‣ Tool
Windows ‣ Terminal.

raywenderlich.com 34
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

It might take a few minutes to complete. When it’s done, you’ll see in the output:
Wrote HTML report to <filename>. Open that file in your browser to see a list of
lint warnings.

Scroll down until you see Usability, Accessibility, and Internationalization. These
are the warnings that matter for this book.

Note: If you see lint errors as raw text, make sure that filename has the .html
extension.

List of linter warnings.


To learn more about each warning, including its location in the code, click the
hyperlink. Start by selecting ContentDescription.

The second way to see the results is right in your code. In the HTML output, you can
see that contentDescription is missing from fragment_discover.xml. Go to that
file and look at the ImageView named discover_button_discard. Hover your
mouse over the ImageView text.

Missing contentDescription attribute on image.

raywenderlich.com 35
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

Phew! This is a bit of a mess with all these warnings. Good thing you’re here to fix it!
The Android system does much of the work of supporting accessibility for you.
Because of that, many of the changes you need to make take only a line or two of
code.

Understanding content descriptions


That contentDescription warning is one of the accessibility components. But what
does it mean?

Assistive technologies, such as screen readers, use content descriptions to


communicate what’s on the screen to a user. The system already knows how to read
many views. For example, it will read the text for a TextView. Images are much
harder to infer without your help.

By adding a contentDescription to an image or image button, you help the user


know what the item is and its purpose. In short, this description will literally tell the
user it’s a “Save button”, so the user knows how to save their changes. Without a
contentDescription, the user would hear “unlabeled button”. You’ll learn more
about these in Chapter 3, “Testing & Tools”.

Details description vs missing contentDescription.


There are quite a few descriptions to add. You’ll get your hands dirty with them over
the next several sections.

Adding content descriptions


Open fragment_discover.xml. The first element you’ll fix is the topmost ImageView
with the contentDescription warning that has the ÍD discover_button_discard.
This is the thumbs-down button on the first screen that you tap to pass on a recipe.

raywenderlich.com 36
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

For icons that act like buttons, like this one, it’s best to use a single verb to describe
the view. For this view, use Discard because you’re discarding the recipe to look at
the next. Lucky for you, there’s a String resource named shared_discard in use
throughout the app!

Add this contentDescription attribute to the ImageView with the ID


discover_button_discard:

android:contentDescription="@string/shared_discard"

This makes it so that accessibility services, and the people who use them, know to
use this button to discard a recipe.

Notice that the description doesn’t contain the word button. The system can
decipher when a component is clickable. The system communicates that state to the
user. As a rule, you don’t need to use words like “button” or “label” in your
descriptions.

One line makes a difference to the user experience!

In fragment_discover.xml, add the following to the ImageView with the ID


discover_button_try:

android:contentDescription="@string/shared_try_it"

Here you’re setting a content description for the Try it image.

Good work! That’s one more view that accessibility services can correctly interpret.
Now the user will understand this button saves the recipe to the “Try it” list.

Run the linter again and you’ll see two fewer warnings — and you only needed two
little lines!

Adding More Content Descriptions


You’re a pro at this now! See if you can work through the following content
descriptions with minimal instruction. If you get stuck, check the solution in the
final project for this chapter.

Find the views in the following files and add the given content descriptions:

• In fragment_recipe_detail.xml, add the content description @string/


shared_try_it to the ImageView with ID recipe_detail_try_discard_button.

• Likewise, in item_try_it_recipe.xml, add the content description @string/


shared_details to the ImageView with the ID item_recipe_details.

raywenderlich.com 37
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

Great! You took care of two more views.

For now, make this your practice: Pick a verb for a button that performs an action.
For other images, follow the pattern object + action + context. For example: “A
person eating a taco on a Tuesday”.

In Chapter 4, “Perceivable — Layout & Labeling”, you’ll learn more about writing
good content descriptions.

Programmatically Adding Content Descriptions


Sorry to inform you, but there’s one issue with your changes to
recipe_detail_try_discard_button. Depending on whether you’ve saved the
current recipe to try later or not, this view toggles between “Try it” and “Dismiss” in
its behavior. This means you also need to toggle the content description. Next, you’ll
implement a bit of Kotlin code to fix this issue.

As with most view attributes, you can set the contentDescription


programmatically. Go to RecipeDetailFragment.kt to set this view. Find the two
methods — showEditableFields() and hideEditableFields().

At the top of each of these, you already have the image set to thumbs-up or thumbs-
down on recipeDetailTryDiscardButton. This is where you’ll set the content
description.

At the top of showEditableFields(), add the following content description:

recipeDetailTryDiscardButton.contentDescription =
getString(R.string.shared_discard)

Now, when the view is thumbs-down, the content description is “Discard”.

To do the same for the opposite state, add this to the top of hideEditableFields():

recipeDetailTryDiscardButton.contentDescription =
getString(R.string.shared_try_it)

Great! Now, when the button changes state, the content description changes with it.

Run lint now. You’ll see fewer ContentDescription warnings — there should be three
left. You’ll handle these slightly differently from the rest.

raywenderlich.com 38
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

Ignoring Views
When you design for accessibility, you need to think about two types of content:

• The content you create, which you can describe.

• The content the user uploads, which you can’t possibly know how to describe —
unless you have supernatural abilities and can predict what future users will
upload.

But seriously, how do you support accessibility for user-generated content? For
example, in the app, each recipe has a different image. Eventually, these images will
come from users, so you need to consider the problem now.

There are two standard solutions for this situation:

1. Ask the user to describe the image. Then you can include that description in the
API response and set it to contentDescription.

2. Tell the accessibility services that this view isn’t important for it to read so it will
skip the view.

The simplest answer is the second solution.

You already learned how to set a String resource as contentDescription, which


you should do for the content you provide. This time, you’ll tell the system that it
shouldn’t read the view by setting contentDescription to @null.

In fragment_discover.xml, find the ImageView with the ID


discover_recipe_image. This is the image that comes with the recipe.

Add @null as the contentDescription for the view with ID


discover_recipe_image:

android:contentDescription="@null"

Perfect. Now the screen reader has the information it needs about this image.

Note: In Chapter 4, “Perceivable — Layout & Labeling”, you’ll learn about


importantForAccessibility, which sends a similar message but has slightly
different behavior.

raywenderlich.com 39
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

Now, run the linter. Oh, look! There’s another case where it feels uncertain about the
content description text: decorative views.

Two more linter warnings.

Handling Decorative Views


Go to fragment_recipe_detail.xml and find a view with the ID
recipe_detail_divider. As the name suggests, this view is a thin line that acts as a
divider between sections. What should the user know about this?

Because it’s a decorative view, it doesn’t add any meaning. You can safely ignore
decorations using android:contentDescription="@null". This guideline applies
to elements like dividers or gradients.

You could add that here. However, you have another option!

This doesn’t need to be an ImageView. Instead, you’ll set it as a plain old View with
the color as the background. Change ImageView to View:

<View

And replace android:src with android:background:

android:background="?colorControlHighlight"

raywenderlich.com 40
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

The final view should look like this:

<View
android:id="@+id/recipe_detail_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?colorControlHighlight" />

Notice that the linter warning doesn’t appear in Android Studio anymore. That’s
because accessibility services skip these View elements unless you signal that a view
is important for accessibility.

Throughout this book, you’ll learn some ways to tell the accessibility services how to
treat a plain view. Content description is only one of them.

Run the linter again. There’s one ContentDescription warning left. You’ll have the
opportunity to fix it in the challenge at the end of this chapter.

Only one linter warning.

Jetpack Compose Tip: Composables such as Icon and Image have a


contentDescription parameter to remind you to include a description. In
cases where this isn’t available, you can use the semantics modifier:
Modifier.semantics { contentDescription = "Edit" }.

But wait! You need to learn how to handle another common warning before you can
call this chapter complete.

raywenderlich.com 41
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

Fixing Keyboard Inaccessible Widgets


When you run the linter, you’ll see KeyboardInaccessibleWidget amongst the
warnings. Find and click it to go to the detailed list of files.

KeyboardInaccessibleWidget warnings.
This warning happens when you declare a view as clickable but not focusable. When
you do this, you make the view interactive for people who tap it to perform the
action, but not for someone who’s using a keyboard or similar technology to access
it.

Often with keyboards, you first need to focus the view, then select it. If it’s not
focusable, the user can’t perform the action. Again, this is something you can fix
with only one line of code!

Open fragment_discover.xml, where all these warnings live. Find the ImageView
with the ID discover_button_discard. Add the following property to the view:

android:focusable="true"

And that’s all it takes! By adding the focusable property, you inform the system to
let keyboard users focus on it.

raywenderlich.com 42
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

While you’re at it, add the same property to the other two views in this file that need
it. These views have the IDs discover_button_try and
discovery_card_detail_button.

android:focusable="true"

Run the linter. You’ve solved so many accessibility warnings! There should be much
fewer. You’ll continue solving these throughout the book.

Build and run. It should behave the same as before when you’re not using
accessibility services. In the next chapter, you’ll learn how to use accessibility
services so you can experience the impact of your changes.

Now that you’ve gotten your hands dirty, and are hopefully ready to focus on some
theory, this chapter will pivot to bring you up to speed on accessibility guidelines.

Defining WCAG
This book teaches you the best practices for and conforms to the Web Content
Accessibility Guidelines (or WCAG) version 2.1 as the standard for accessibility.
These guidelines are an industry standard.

WCAG is exactly as the name suggests: a guideline for making your web content or
app accessible. The guidelines help you build your app so it’s consumable to a wide
range of people. It doesn’t address every user’s needs — nor does this book — but it
covers the main points and best practices.

Even though the guideline’s title suggests they are for the “web”, they’re useful for
Android engineers to follow, and here’s why:

• Used for legal requirements: Remember the legal requirements you learned
about in Chapter 1, “Why Accessibility”? Many legal battles use WCAG as the
guidelines for how to comply with accessibility laws across countries. That alone
should make it a priority for you to learn.

• Common language with others: You can use these guidelines across platforms.
This means that you can talk about accessibility using this language with iOS and
web engineers, as well as customers, product managers and designers.

• Written with mobile in mind: As of version 2.1, WCAG includes requirements


that apply to websites, mobile apps and tablets.

raywenderlich.com 43
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

Note: As an example, the content descriptions you added help you satisfy the
first requirement:

Guideline 1.1 Text Alternatives: Provide text alternatives for any non-text
content so that it can be changed into other forms people need, such as large
print, braille, speech, symbols or simpler language.

You’ll dig even deeper into this guideline in Chapter 4, “Perceivable — Layout &
Labeling”.

Building a POUR App


WCAG uses a lovely little acronym to categorize the principles of the requirements:

• P erceivable

• O perable

• U nderstandable

• R obust

Perceivable, Operable, Understandable, Robust.


This book is organized by these principles, and you’ll learn more about each of them
as you go. Let them serve as a mental checklist: “Is my app perceivable, operable,
understandable and robust?”

Content descriptions fall under “perceivable”. They allow your user to perceive
what’s in an image or understand a button’s purpose.

Making a view both clickable and focusable falls into the “operable” category. It lets
people using a keyboard operate your app.

raywenderlich.com 44
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

Measuring Using Levels of Compliance


WCAG provides levels of conformance for each of its guidelines, which include A,
AA, and AAA, going from lowest to highest. Level A conformance means you’ll meet
most people’s needs. The industry best practice is to meet at least A or AA.

Guideline 1.1 Text Alternatives, which covers content descriptions, is level A. It’s one
of the first guidelines, and all apps should conform to it.

Note: This book will reference WCAG and the Android resources throughout.
If you’re curious enough to look into these, head to WCAG at https://
www.w3.org/TR/WCAG21/ and the Android docs resource at https://
developer.android.com/guide/topics/ui/accessibility.

Choosing Universal Design


There are two predominant strategies for designing accessible apps: accessible
design and universal design.

• Accessible design is self-descriptive: It’s design that makes your app accessible.
Features could be accessible in and of themselves, or you could create a tailored
experience so someone using assistive technologies gets a different version of the
app.

• Universal design is a subset of accessible design, with the intent being to ensure
that everyone gets the same experience. The design is accessible by default, so you
don’t need to create a second design specifically for those using assistive
technologies.

“The intent of universal design is to simplify life for everyone by making


products, communications and the built environment more usable by as many
people as possible at little or no extra cost. Universal design benefits people of
all ages and abilities.”

-The Center for Universal Design at NC State University College of Design

raywenderlich.com 45
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

This book uses universal design wherever possible because it makes your user
experience consistent for all users, and it protects user privacy. With universal
design, you don’t need to pry into your users’ data to see if they use assistive
technologies.

At this early stage in the book, you’re already better equipped to start improving
accessibility in any app! Before you move on to the next chapter, here’s an
opportunity to practice what you’ve learned already.

Challenges
Challenge 1: Solve the ContentDescription
warning
Remember, the last time you ran the linter there was one more ContentDescription
warning. Now’s the time to show your stuff by solving it!

In item_onboarding.xml you’ll see an ImageView with the ID onboarding_image.


This is the view with the linter warning. If you remember, the on-boarding screen
has an image with each slide. How do you think these should behave?

For this challenge, solve the ContentDescription warning on the on-boarding


screen. You’ll need to decide whether to ignore it or add a description. If you get
stuck, review the solution in the challenge project in the chapter materials.

Some tips and hints:

• To see the on-boarding screen again when you run the app, check Show on-
boarding in the Settings screen. Then, next time you close and open the app you’ll
see the on-boarding screen.

• If you decide to set the content description programmatically, set this view’s
properties in OnboardingPagerAdapter in OnboardingActivity.kt.

• Again, if you set the content description programmatically, make the warning go
away in the XML file by either adding a placeholder content description or by
suppressing the lint using tools:ignore="ContentDescription". If you
suppress the warning like this, it’s helpful to add a comment to clarify that it’s set
programmatically.

raywenderlich.com 46
Android Accessibility by Tutorials Chapter 2: Hello, Accessibility!

Key Points
• Android lint is a useful tool for identifying accessibility issues.

• One or two lines of code can often solve accessibility warnings.

• Content descriptions tell accessibility services what a given image is.

• To improve keyboard users’ experiences, add android:focusable="true" to a


view that you declare android:clickable="true".

• WCAG and the Android docs are excellent resources for understanding
accessibility requirements.

• Choose universal design over accessible design so that everyone has the same
experience in your app.

Where to Go From Here?


Congrats! You’re already making great improvements to the app. If you got stuck at
any point, check out the final and challenge projects included in the chapter
materials.

Think about the huge impact you’ve already made on this app. Before your changes,
there was no straightforward way for a person using a screen reader to know how to
save a recipe, and there would be no way for someone using a keyboard to dismiss a
recipe to move to the next.

Before you can get much further with your new knowledge, you’ll need to learn more
about the common assistive technologies people use and about testing technologies
that can detect potential issues. Move on to the next chapter to fill in those gaps and
move one step closer to being an accessibility detective!

raywenderlich.com 47
3 Chapter 3: Testing & Tools
By Victoria Gonda

Accessibility services are among the many tools Android provides for users. Some
people depend on these services to view and navigate apps. Learning how to use
these tools for yourself will help you get a clear picture of how your app interacts
with these services. It will also help you develop empathy for your users who rely on
these services.

Some tools automatically detect accessibility issues in your app. They include
standalone scanners, as well as tools that integrate into your automated testing and
IDE.

In this chapter, you’ll learn about these tools and testing for accessibility so that, as
you work through the remaining chapters, you’ll be able to verify the improvements
you’re making.

To get started, you need to make sure you have these tools set up on your device.

raywenderlich.com 48
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Setting Up Your Device


You’ll need these three tools installed on your device or emulator:

• Accessibility Suite

• Accessibility Scanner

• Voice Access

Most modern physical devices come with some of the services found in the
accessibility suite. Depending on your device, you may have some services but not
others. If you don’t see a certain service, often you can set up an emulator that has
that service and carry on.

Prepping Your Emulator (Optional)

Note: Many of these tools work better on a physical device than an emulator,
so use that option if you have it. If you’re using a physical device, you can skip
ahead to Downloading Tools.

If you already have an emulator, check the apps list to see if the Play Store is
installed. If yes, you can skip ahead to downloading. If not, follow the next steps to
learn how to set up an emulator with the Play Store.

Play Store icon in the apps list.

raywenderlich.com 49
Android Accessibility by Tutorials Chapter 3: Testing & Tools

The simplest way to get the Play Store on an emulator is to create an emulator
through Android Studio. Go to Tools ▸ Device Manager, or click the Device
Manager icon in the toolbar.

Device Manager icon.


If you have another emulator set up with the Play Store, you’re welcome to use that.
Not sure if you have one? In your list of emulators, look for one that has the Play
Store icon.

List of emulators with Google Play description.


If you need to create an emulator, click Create Device at the bottom of the window.

Create Device button.

raywenderlich.com 50
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Then, choose a Phone that has the Play Store icon and click Next.

Device option with Play Store icon.


After that, pick the latest system image. Click Next. Keep all the defaults and click
through the remaining steps in the wizard. Click Finish at the end.

Boot your new emulator and you’re ready to start downloading the tools you need.

Downloading Tools
The first thing to download is the Android Accessibility Suite, a set of tools that
people with disabilities use to navigate their devices.

Review which accessibility services you have installed by going to Settings ▸


Accessibility. You may have a long list or nothing at all.

If you see tools like TalkBack and Select to Speak, then you have what you need for
this book. Some phones come pre-packaged with these services.

Accessibility items in the settings screen.

raywenderlich.com 51
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Otherwise, head over to the Play Store and sign in with a Google account. Search for
and download Android Accessibility Suite.

Android Accessibility Suite in Play Store.

Note: If your downloads get stuck at Download pending, long-press the


power button on the emulator. Select Restart to reboot it. The pending
download should be installed when you reboot. You may have to do this once
per app.

Once the downloads finish, review the full suite of tools in the Accessibility Settings
at Settings ▸ Accessibility. You’ll learn how to use many of these tools in this
chapter.

You need one more service. In the Play Store, search for and download Accessibility
Scanner.

Accessibility Scanner in Play Store.


You can see this app in your apps list. When it’s time to use it, you’ll turn it on
through the Accessibility Settings screen.

Finally, install Voice Access. This one is optional, as it may not be available on
emulators or older devices. Search for Voice Access in the Play Store. If it’s there,
download it.

Voice Access in Play Store.


Now that you have everything installed, it’s time to learn how to use these tools.

raywenderlich.com 52
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Using Accessibility Services


You already know there are many accessibility settings — too many to cover in this
chapter. You’ll learn about the ones that are most likely to affect the way you build
your app. Keep in mind that not all of these accessibility tools are available on every
device. If you don’t see one of the tools listed above, likely, your device doesn’t
support it. In that case, you should set up an emulator using the steps above so you
can follow along. Emulators don’t have all services, but they could have some that
your device is missing.

Note: Consider these optional settings to make navigation easier: Turn on the
Accessibility Menu at Settings ▸ Accessibility ▸ Accessibility Menu, and turn
on three-button navigation at Settings ▸ System ▸ Gestures ▸ System
Navigation. Keep in mind that this is not available on some emulators.

Note: When working with the settings below, some emulators and devices may
have subtle variations in terms, features and locations in settings.

Select to Speak
The first service you’ll try is Select to Speak. Go to Settings ▸ Accessibility ▸ Select
to Speak and toggle the Select to Speak shortcut switch to on. You’ll see a
permissions dialog pop up. Tap Allow.

Accessibility permissions dialog.

raywenderlich.com 53
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Note: Many of these accessibility services require explicit permission to view,


change and perform actions on the screen. When you see them as you’re
working through this book, always choose Allow.

To use this service, tap the Accessibility icon in the navigation bar.

Select to Speak floating button.

Note: On some devices you may need to press an accessibility (stick figure
person) icon in the navigation bar instead.

This will bring up a control. Tap the Play triangle so it reads everything on the
screen. Pick your favorite app and tap the triangle to try it out.

Select to Speak control.


Now click and drag to highlight a section of the screen. Select to Speak will read all
the text on that part of the screen. Pick another screen, turn on this tool from the
navigation bar, and click and drag to read the views included in the selection.

Select to Speak reading a selection.

raywenderlich.com 54
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Pretty neat! Examples of people who might use this service include those with vision
impairments and those who struggle with reading.

Try it out as much as you like. Then, go back to Settings and turn it off the same way
you turned it on before.

Switch Access
While Select to Speak allows you to read items on the screen, Switch Access enables
you to navigate. It’s helpful for users who have limited mobility.

You generally use Switch Access with special hardware that has two or more buttons.
One button moves to the next element on the screen, while the second selects the
current element.

Example of a switch.
Most people don’t have this kind of switch lying around, so you’ll set up your device
to use the volume keys as buttons.

Note: Not all devices have this option. If you don’t see the option to assign
keys and you’re working with a physical device, you can try Camera Switches
(https://support.google.com/accessibility/android/answer/11150722).

Find Switch Access in the Accessibility Settings and go to Switch Access ▸ Settings
▸ Assign switches for scanning. Tap the option for Select.

raywenderlich.com 55
Android Accessibility by Tutorials Chapter 3: Testing & Tools

A screen will pop up that allows you to assign a button for Select.

Set switch screen.


Rather than select anything on this screen, press the Volume Down button. You’ll
see the selected key listed. Then tap Back to save. You’ve assigned your first switch
for selecting views. Do the same thing to assign Next to the Volume Up button.

Volume down set for Select.

Note: You can choose other buttons if you like. If you’re using an emulator or
have an attached external keyboard, you can even use a key on your keyboard.

You’re all set to use Switch Access! Go back to the root Switch Access screen in
Settings and toggle on Use Switch Access. Try using Volume Up to walk through
onscreen items, and Volume Down to “tap” an item.

After you’ve navigated a couple of views, go back to the Switch Access view and turn
off the service.

raywenderlich.com 56
Android Accessibility by Tutorials Chapter 3: Testing & Tools

TalkBack
TalkBack combines reading and navigating into one service. With TalkBack, you can
use gestures or a keyboard to navigate the screen, and the device reads the contents
out loud. This tool is great for users with low or no vision.

Find TalkBack in the Accessibility Settings and toggle the switch on. If this is your
first time turning TalkBack on, you’ll see a tutorial — go through it. If you don’t see
the tutorial, you can still access it. Go to the TalkBack screen then select Settings ▸
TalkBack tutorial.

If you don’t use the tutorial, here are the basic gestures to know:

• Swipe right advances to the next item on the screen.

• Swipe left navigates to the previous item.

• Double-tap to select an item.

• Single-tap to navigate when swiping on an emulator proves difficult for you.

Try swiping left and right to move around the screen and double-tapping to select.
When you’re done, navigate back to the TalkBack screen and double-tap on the
switch to turn it off.

Note: You can turn TalkBack on and off via the command line using ADB, too.
To turn TalkBack on:
adb shell settings put secure enabled_accessibility_services
com.google.android.marvin.talkback/
com.google.android.marvin.talkback.TalkBackService

And to turn it off:


adb shell settings put secure enabled_accessibility_services
com.android.talkback/
com.google.android.marvin.talkback.TalkBackService

It helps to set up an alias if this is your preferred method to turn TalkBack off
and on.

Think back to all the content descriptions you added in Chapter 2, “Hello,
Accessibility!” for services like TalkBack. Now you can see and hear why they are
crucial to some users.

raywenderlich.com 57
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Other TalkBack Gestures


You can do more than next, previous, and select with TalkBack gestures.

Go to TalkBack settings and find Gestures. Look at the list of possible gestures. For
example, you can swipe up then down to focus the first item on the screen.

You don’t need to memorize these as long as you know the basics:

• Swipe right for next

• Swipe left for previous

• Double-tap to select

TalkBack Settings
There are more settings available. If you have developer options turned on, you can
set it so that the content that’s read is also printed onscreen. To turn on developer
settings, go to Settings ▸ System ▸ About device (on an emulator, this will be
Settings ▸ About Emulated device) and tap the build number seven times.

To make the device display the text it’s reading, go to TalkBack settings, scroll
down and select Advanced settings ▸ Developer settings then toggle on Display
speech output.

If you’re feeling brave or well-practiced with TalkBack, try dimming the screen while
TalkBack is on to simulate vision impairment. To turn this on, with TalkBack
enabled, swipe down and to the right to open the Global Context menu. Select Hide
screen. This will make the screen dark, preventing you from seeing the items you’re
selecting. To turn it off, swipe down and right again, then select Show screen.

Navigating using a keyboard (optional)


If you’re using an emulator or have a keyboard attached to your device, you can
navigate with a keyboard.

If you have a keyboard connected, go to Settings ▸ Advanced settings ▸ Keyboard


shortcuts on the TalkBack screen. By default, you should have Default keymap for
Choose a keymap and Alt for Choose a modifier key.

raywenderlich.com 58
Android Accessibility by Tutorials Chapter 3: Testing & Tools

On this screen, under Navigation actions, you can see which keys map to which
actions. The most important ones to know are:

• Alt + Arrow Right to navigate to the next item.

• Alt + Arrow Left to navigate to the previous item.

• Alt + ENTER to select.

Voice Access
Voice Access is a hands-free way to control a device. By saying commands like “Type
Hello World”, “Back” and “Submit”, a user can type in an edit field, close the
keyboard and submit a form.

You should have Voice Access downloaded, so go to Voice Access in the Accessibility
Settings to turn it on. Go through the tutorial when prompted.

There are three ways to navigate using Voice Access. You can say the text of the
element, say the number that’s next to it, or use a grid system to narrow down a
view.

Item selection next to grid selection.


This service is mainly used when someone has limited or no mobility. It’s also
helpful when you can’t touch the screen, such as when your hands are busy making
tacos or soapy from doing dishes afterward.

Adjusting Size
When you live with vision limitations or your device is far away, adjusting the size of
what’s onscreen can do wonders. Android has three ways to do this.

raywenderlich.com 59
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Font Size
You can scale the font size across apps. Go to Display size and text in Accessibility
Settings. This might also be called “Font size” or “Text and display” depending on
your device. Use the slider at the bottom of the screen to scale the text to Largest.
Use a few of your favorite apps to see how they look. Text that used to fit on one line
might now be on two lines or be truncated.

Display Size
Changing the display size is much like scaling the text. The difference is that it also
changes the size of non-text elements, such as icons. Go to Display size and text in
Accessibility Settings to try it. This might also be called “Display size” depending on
your device.

Magnification
Unlike scaling, which has a universal effect, magnification allows you to zoom in on
any screen. Go to Magnification in Accessibility Settings. If you have the option, go
to Magnification shortcut. Turn the service on.

Try it out. Tap the shortcut to zoom in then use two fingers to scroll or even zoom in
further. Tap the shortcut again to un-zoom.

Note: Your controls might be slightly different. Follow the instructions


described on the settings screen.

Modifying Colors
Changing colors can provide a better experience for users with vision disabilities.
People may also use these options because of their preferences. Try out each of
them, one at a time, turning off one before you move to the other.

Dark Theme
Did you know that the dark theme is also an accessibility feature? Since Android 10,
you can activate dark mode from Settings ▸ Display ▸ Dark Theme but you can also
set it in Settings ▸ Accessibility ▸ Color and motion ▸ Dark Theme on some
devices. Surely, you already know which setting you prefer!

raywenderlich.com 60
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Note: While these options might be availbe on your emulator, there are some
emulators where you wont see a change when you turn them on.

Color Inversion
Somewhat related to the dark theme is Color inversion. As the name suggests, this
takes all the colors on the screen and inverts them. Unlike the dark theme, it also
inverts photos. Try turning on Color inversion at Settings ▸ Accessibility ▸ Color
and motion. Note that on some devices this may be under Settings ▸ Accessibility
▸ Color and motion.

High Contrast Text


High contrast text is a setting that increases the contrast between the text color
and the background color. Go to Settings ▸ Accessibility, then toggle on High
contrast text to see how it makes the text more distinct on the screen.

Color Correction
The color correction setting can help with color blindness. Turn on Color
correction in Settings ▸ Accessibility ▸ Color and motion. Try the different types
of color correction to see how it changes the colors on your screen.

Simulating Color Space


Rather than being an aid for users with disabilities, this tool is for developers to
simulate color blindness. Go to Settings ▸ System ▸ Developer options and scroll
(way) down to Simulate color space. Try the different options in multiple apps.

Did you notice any places where low contrast made it more challenging to see
something?

Showing Captions
Newer devices come with Live Caption. This feature detects when the device plays
audio with speech and displays captions. Like the other services, you enable this in
Accessibility Settings. Look for Caption, turn it on then play a podcast or other
audio with talking in it.

raywenderlich.com 61
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Disabling Animations
Although some users love animations, for others, they can be distracting or even
nauseating. That’s why there’s an option to turn them off. Go to Settings ▸
Accessibility ▸ Color and motion ▸ Remove animations and toggle the switch on.
On some devices this may be under Settings ▸ Accessibility ▸ Text and display ▸
Remove animations The change is typically subtle. Notice that when you switch
apps, you no longer see the animated transitions.

Accessibility Services
Many of these tools hook into the same accessibility services. These services
communicate with app views to understand the content and what actions are
possible. They know the bounds of each view and can decipher if something
important changed.

You’ll learn more about how to directly communicate with these services in Chapter
10, “Robust”. Until then, you’ll inform the accessibility services about your views in
similar ways to the content descriptions from Chapter 2, “Hello, Accessibility!”.

Testing for Accessibility


Now that you know how to use many of these accessibility services, you’ll dig into
the best way to test your apps for accessibility. There are many tools available.

Lint Checks
In Chapter 2, “Hello, Accessibility!”, you learned how lint checks help you improve
your app. Lint enables you to maximize accessibility by providing feedback from an
early development stage, right in your IDE.

Espresso Tests
Espresso, one of the leading libraries used for UI tests on Android, also includes
accessibility checks. You don’t even need to write additional tests to use it! It runs
alongside your existing Espresso tests.

Open up the Taco Tuesday project in Android Studio. You can either continue where
you left off or work with the starter project for this chapter.

raywenderlich.com 62
Android Accessibility by Tutorials Chapter 3: Testing & Tools

There’s a UI test already written for you. Open DiscoverFragmentTest.kt and try
running it by clicking the Play button in the gutter next to the class name.

Note: You may need to turn off animations on your device to run these tests.

To add accessibility checks, start by adding the accessibility Espresso add-on library.
In the app level build.gradle, add this to the list of dependencies.

Make sure this is all on one line:

androidTestImplementation
"androidx.test.espresso:espresso-accessibility:3.4.0"

Sync the Gradle file. Now, go back to DiscoverFragmentTest and add this code to
the bottom of setup():

AccessibilityChecks.enable()
.setRunChecksFromRootView(true)

This enables accessibility checks. It will provide accessibility suggestions on any


view where you perform a view action, and setRunChecksFromRootView(true)
ensures these checks occur on descendant views.

Another option is to enable these checks in your test runner instead of enabling
them for all your tests.

Run the tests. The tests should fail with an AccessibilityViewCheckException:

There were two accessibility errors.


Below there are details about why a view failed:

Minimum touch target size is 48x48dp.


You’ll come back to these tests and fix these issues later in the book.

raywenderlich.com 63
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Until then, you’ll instruct the Espresso Accessibility Library to ignore some issues.
Add the following to the AccessibilityChecks method chain you have, importing
org.hamcrest.Matchers.anyOf:

.setSuppressingResultMatcher(
anyOf(
matchesViews(withId(R.id.discover_button_discard)),
matchesViews(withId(R.id.discover_button_try))
)
)

This suppresses any accessibility errors with the IDs discover_button_discard and
discover_button_try. You can use any ViewMatchers here, so it’s possible to
match by any view attribute or a collection of views.

You can also suppress a specific type of issue with


matchesCheckNames(`is`("TextContrastViewCheck")).

Rerun the tests. There should no longer be any accessibility errors.

Accessibility Scanner
Remember the Accessibility Scanner you downloaded near the beginning of this
chapter? Now you get to try it.

Head back to Accessibility Settings and find Accessibility Scanner. Toggle it on and
accept all the prompts. A blue check mark will show up on the screen when you exit
Settings.

Blue check mark.


Run the Taco Tuesday app to scan.

Tap the blue check mark to scan the screen. Pick Snapshot to scan what’s currently
onscreen or Record to continuously scan as you move through the app. For this
exercise, tap Snapshot.

raywenderlich.com 64
Android Accessibility by Tutorials Chapter 3: Testing & Tools

You’ll land on a results screen that shows boxes around all the service’s accessibility
suggestions.

Accessibility Scanner suggestion boxes.


Tap one of these boxes to see details about the suggestions.

Accessibility Scanner suggestion details.


Throughout this book, you’ll return to this tool to check your improvements. Keep in
mind when using this tool that these are suggestions. It’s up to you to determine if
it’s an issue. You also have to decide how to resolve it

Note: Other scanners do a similar job. For example, you can download Axe
from the Play Store and try it out.

raywenderlich.com 65
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Manual Testing
You’ve already been manually testing in this chapter, and it’s one of the most reliable
ways to test your app. Use the tools you learned above, such as TalkBack, to see how
your app behaves. Is something hard to see or do with one of these tools? If so, you
know there’s a potential issue.

Although tools such as Espresso tests and the Accessibility Scanner adeptly spot
potential pitfalls, you don’t want to rely on them. They lack a comprehensive picture
of how your app behaves. Only humans can assess your app’s accessibility.
Experimentation, QA and user testing are the ultimate accessibility tests.

Knowing How Much To Test


So many tools. Are you feeling overwhelmed? It’s okay to start small. Running these
scanners on an existing multi-screen app can be a chore. Don’t run boldly into a
testing scenario without developing a strategy first. You need a strategy to define the
desired level of conformity and what you need to do to achieve it. Then figure out
how much you can spend on time, money and resources. This strategy will look
different for each team.

If you’re on a small team, accessibility usually becomes the individual engineers’ and
designers’ responsibilities. Although accessibility has to be juggled with other day-
to-day tasks, a small team has the advantage of tight feedback loops. You must set
standards, boundaries and clear expectations for accessibility. You need to be
intentional in your approach.

You have more flexibility if you’re on a larger team — especially if you’re large
enough to have designated engineers, contractors and accessibility QA testers. Large
teams have the advantage of more resources to dedicate to accessibility. The
challenge for large teams is communication. It’s more challenging to keep several
people on the same page and to clearly define roles and responsibilities when many
hands are involved. In addition to defining roles, you have to establish processes for
the team to follow. Each team member must know what to do, when to do it and who
needs to sign off on the work.

raywenderlich.com 66
Android Accessibility by Tutorials Chapter 3: Testing & Tools

Regardless of your team size, these questions will help you put together your testing
strategy:

• How much time and which resources do you have to put towards this?

• What level of conformity do you want to have? Reference the WCAG standards
from Chapter 2, “Hello, Accessibility!” for this question.

• Which screens take priority? Are your highest trafficked or entry screens
accessible? Which items from your roadmap require extra accessibility work?

• How can you make accessibility sustainable for your team?

These are questions to get you thinking about how building accessibility into your
team’s daily routine might look. They’ll also help you define what’s “good enough” at
a given time. There’s much more about this in Chapter 12, “Getting Your Team on
Board”.

Key Points
• Download Accessibility Suite and Accessibility Scanner from the Play Store.

• Select to Speak, Switch Access, TalkBack and Voice Access are all ways of viewing
and navigating your device.

• Users can change the size of views with magnification and adjust the font size and
display size.

• Color settings can change to suit the user’s preferences.

• Captions can make audio accessible for those with hearing impairments.

• Animations can be disabled for users who find them to be unhelpful or


distracting.Use lint checks, Espresso tests, Accessibility Scanner and manual
testing to measure your app’s accessibility.

• Using the accessibility tools for yourself is the ultimate way to understand your
app’s accessibility.

• Strategy is critical to successfully implementing accessibility support in your app.

Now that you’ve explored some accessibility tools, it’s time to dive deeper and learn
more about content descriptions and layouts to make the app more perceivable.

raywenderlich.com 67
4 Chapter 4: Perceivable —
Layout & Labeling
By Victoria Gonda

In this chapter, you’ll continue making improvements to Taco Tuesday. By the end of
the chapter, you’ll have applied what you learned to give the app helpful
descriptions, labeling and layouts that are more perceivable for people using screen
readers and other assistive technologies.

In Chapter 2, “Hello, Accessibility!”, you learned how to add content descriptions and
in Chapter 3, “Testing & Tools”, you learned about screen readers. You should read
both chapters before starting this one.

To learn these topics, you’ll continue working on the Taco Tuesday app. Either open
the project you’ve been using in the previous chapters or find and open the starter
project in the materials for this chapter.

raywenderlich.com 68
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Defining Perceivable
Perceivable is the first category that the WCAG defines for how to make your app
accessible. Here’s the definition provided in the WCAG documentation:

1. Perceivable: Information and user interface components must be


presentable to users in ways they can perceive.

This means that no matter if someone is consuming your app visually or through
audio or touch, they can identify what’s on the screen.

Throughout this book, you’ll see these quotes from the WCAG documentation to
guide you on your way and give you a reference if there’s a topic you’d like to look
deeper into. When it applies, you’ll also see the level they rated the guideline so you
know if you’re reaching Level A, AA or AAA conformity by applying it.

To focus on perceiving the app in a way you might not normally, this chapter will
have a heavy focus on screen readers.

Understanding Screen Readers


While you’ll mostly use TalkBack in this book, there are many screen readers out
there. For example, BrailleBack gives feedback through a braille readout.

Before moving on, it’s good to have a rough idea of how screen readers work. Here
are a couple of tips on screen reader behaviors to help inform the decisions you make
for your app:

1. When screen readers traverse your screen, they read out text and content
descriptions. They also announce an item, such as a button, and any actions that
you can perform.

2. Readers typically traverse a screen from the top down and from start to end.
However, this isn’t always the case — sometimes they follow the view hierarchy.
While the experience is consistent on a given device, it can vary widely across
devices.

3. Finally, readers often have shortcuts to jump to specific parts of the screen. For
example, if you have headers, the user can skip ahead to the next header and
avoid hearing text that doesn’t interest them.

raywenderlich.com 69
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

You’ll use TalkBack and the Accessibility Scanner to verify your work. For a
refresher on how to use these tools, go back to Chapter 3, “Testing & Tools”.

Including Effective Text Alternatives


In Chapter 2, “Hello, Accessibility!”, you learned how to add a content description to
a view, which informs a screen reader about the contents of that view. Content
descriptions are especially important for views without text, such as images and
icons. They help your app adhere to the first guideline:

Guideline 1.1 Text Alternatives: Provide text alternatives for any non-text
content so that it can be changed into other forms people need, such as large
print, braille, speech, symbols or simpler language.

This guideline has one criterion that you need to meet. Lucky for you, you can largely
meet this one using content descriptions.

Success Criterion 1.1.1 Non-text Content: All non-text content that is


presented to the user has a text alternative that serves the equivalent purpose.

Level A

To round out your understanding, here’s a review of what you covered in Chapter 2,
“Hello, Accessibility!”.

In that chapter, you used a linter to identify non-text elements that were missing a
content description. This lets accessibility services know what to do with icons like
the thumbs-up Try It button.

Build and run the Taco Tuesday app. Run TalkBack on the main screen to hear the
content descriptions you added. In fragment_discover.xml, remove the
contentDescription attribute from the ImageView with the ID
discover_button_discard and run it again to notice the difference.

TalkBack response with and without a content description.

raywenderlich.com 70
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Imagine if you couldn’t see the screen. That description makes so much of a
difference!

Replace the contentDescription you removed:

android:contentDescription="@string/shared_discard"

This fixes the temporary change you made so you could see how it behaves with the
screen reader.

Hiding Decorative Content


In Chapter 2, “Hello, Accessibility!”, you also used
android:contentDescription="@null" to signal to the accessibility services that
it can skip that view. This meets one of the detail items under Success Criterion
1.1.1:

Decoration, Formatting, Invisible: If non-text content is pure decoration, is


used only for visual formatting, or is not presented to users, then it is
implemented in a way that it can be ignored by assistive technology.

You used this on the header image on the main Discover screen. Now, follow the
same exercise you did above; try out TalkBack with and without
contentDescription set on the view with ID discover_recipe_image in
fragment_discover.xml.

Make sure you end with that contentDescription back in place:

android:contentDescription="@null"

There are two different ways you can signal accessibility services that they should
ignore a view. Often, they behave the same way but they do behave slightly
differently in some cases:

raywenderlich.com 71
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Setting the Content Description to null


This is the option you’ve used before in this book:

android:contentDescription="@null"

In many cases, when used on a non-textual element, accessibility services will ignore
the view. In some cases, because this view is still available to the screen reader,
accessibility services will still read out some text while exploring the screen. This is
especially true if you’re using this on a textual element, such as hiding decorative
text. The reader will still announce the decorative text.

Setting the ImportantForAccessibility XML


Attribute
Android supports the importantForAccessibility attribute for API 16 and higher.
If a device is running at least Android 4.1, the accessibility services won’t highlight
or read a view with this attribute.

This app includes a good place to apply this option. With TalkBack off, make sure
you have some recipes saved in the app along with the Thanksgiving Tacos recipe,
then go to the list. Notice you can swipe to discard an item.

Screenshot of swiping a card, revealing the discard action.


For this exercise, treat Discard as decorative text.

raywenderlich.com 72
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Now, view the Thanksgiving Tacos recipe with TalkBack turned on. Notice that it
reads Discard along with the rest of the card. The same goes for the rest of the
favorite recipes.

Screen reader reading: Thanksgiving Tacos, Discard.


To make it so the accessibility services ignore this Discard text, open
item_try_it_recipe.xml. Find the TextView with the text @string/shared_discard,
and add the following attribute:

android:importantForAccessibility="no"

Build and run. Look at the Thanksgiving Tacos view with TalkBack again. This time
the reader ignores Discard.

Screen reader reading: Thanksgiving Tacos, In list, five items.

Writing Clear Descriptions


You now know a lot about why and where you should use content descriptions. It’s
also helpful to know how to write a good content description. The best way to write a
description changes depending on what you’re describing.

raywenderlich.com 73
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Describing Icons
Icons are often used as an actionable button or to show a state. When an icon is used
as a button, you often use a verb for the description. If you have a pencil icon button
to edit a contact, Edit contact is much more meaningful than Pencil. You want to
describe what the icon does.

When you have an icon representing a state, the description should generally
describe what the state is. For example, you might have a padlock icon where the
state, and therefore the content description, is Private.

If you have a toggleable icon that’s both actionable and shows state, you usually
describe the state it represents. This is especially true when you’re using a Switch or
Checkbox with a custom-selectable drawable. The system will know to say whether
it’s checked or not. The accessibility service would read: “Favorited, checked” or
“Favorited, unchecked”.

Describing Text
In most cases, you don’t need to add content descriptions to text. The text should
speak for itself. Exceptions include situations where you have a compound drawable
that the user should understand along with the text, or if you have symbols in the
text that the user should perceive differently.

For example, if you have the text: “$5/month” you might want the content
description to read “$5 per month.”

Describing Images
Perhaps one of the hardest types of items to describe are images. There can be a lot
of content in a single image. How much should you share?

You want to be concise enough that it’s consumable, while descriptive enough that
the user understands all the essential parts of the image. One pattern that can help
you achieve this is object-action-context.

To follow this pattern, you start by describing the main object of the photo. Then,
you describe any action that the object might be doing, following the context. An
example of this might be “A person eating a taco at a home dining room table.”

You can judge how much detail your user needs. If you need to add more detail, try
not to be repetitive. Either include the details inline like “A happy person eating a
fish taco at a blue home dining room table with some friends.”

raywenderlich.com 74
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Or, start with the object-action-context pattern, followed by the details. “A person
eating a taco at a home dining room table. The person has long hair and is happy.”

You can also apply these guidelines to GIFs and some videos. As you’re writing these
content descriptions for your app, keep in mind that you should treat them as copy.
People consume these descriptions the same way as other copy in your app.

That’s a lot of information about text alternatives. Now, it’s time to switch gears and
talk about layouts.

Creating Adaptable Layouts


How you lay out your app changes the experience for your users. You want your
layouts to be adaptable for however people are perceiving them. There’s an entire
section of the WCAG about making your app adaptable.

Guideline 1.3 Adaptable: Create content that can be presented in different


ways (for example simpler layout) without losing information or structure.

At a high level, you want to organize your information logically. Keep in mind that
most screen readers (and humans!) start at the top of the screen, and work their way
down. There are lots of other ways you can improve your layout as well.

Notating Headers
Using headers is an effective way of organizing your content. It allows a person to
identify and skip directly to the section that interests them. It associates the content
in that section with a common topic.

Screen readers also use this organization. A person using assistive technology can
navigate and perceive the content in your app more easily if you provide this
structure. Headers are one way of meeting Success Criterion 1.3.1:

Success Criterion 1.3.1 Info and Relationships: Information, structure, and


relationships conveyed through presentation can be programmatically
determined or are available in text.

Level A

raywenderlich.com 75
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Assistive technologies don’t automatically know which TextViews are headers in


your app. You need to inform them. Much like the other topics covered here, you can
do this through an attribute in the XML: android:accessibilityHeading.

Open the app and look at the details of a recipe. There are sections for different parts
of the recipe such as the base layer and mixin. These sections each have a label that
you can treat as a header.

Screenshot of example header, circled.


Go to fragment_recipe_detail.xml. Your next step is to add this heading attribute to
each of these TextViews. There are seven TextViews with the style @style/
AppTheme.TextKicker. Search for each and add the following attribute:

android:accessibilityHeading="true"

You might see a warning that this attribute is only available on API level 28 and
higher. That’s OK! There’s a way to accomplish the same thing using
AccessibilityNodeInfoCompat. You’ll learn more about this class later in the book.

Now, for accessibility services that support it, users can jump between headers. The
header is also announced as a header.

While using TalkBack, you can navigate through the headings by opening the local
context menu using the swipe up then to the right gesture or Alt-Shift-Space with
the keyboard.

Build and run to see your changes. Go to the details for any recipe. With TalkBack
turned on, open the local context menu and pick Heading. Navigate this screen as
you would normally, this time skipping from heading to heading.

raywenderlich.com 76
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Note: If you don’t see a “Headings” or “Navigation” option, you may need to
go to the TalkBack settings an add it under Customize TalkBack menu.

When you’re done, open the local context menu again and switch back to Default so
you can move on to the next topic.

Grouping Related Items


Another way you can make the screen easier to navigate is by grouping items. It’s
tedious to walk through every single item to get to the content you want. By
grouping related items together, you can remove unnecessary steps.

Success Criterion 1.3.2 Meaningful Sequence: When the sequence in which


content is presented affects its meaning, a correct reading sequence can be
programmatically determined.

Level A

For an example of how this looks, imagine you have a label and a value. Rather than
requiring the user to read Total, then swipe to the next item to hear $5.43, they can
hear the group: Total: $5.43, altogether.

You can group items by making the shared parent view focusable. Try this by
grouping the nacho and spice rating bars with their labels that show on the Detail
screen when you have a recipe saved.

Screenshot of nacho and spice rating bars.


Open fragment_recipe_detail.xml and find the LinearLayout with the ID
recipe_nacho_rating_container. This layout contains both the rating bar and the
heading label.

raywenderlich.com 77
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Add the following attributes to the LinearLayout :

android:focusable="true"
android:focusableInTouchMode="false"

android:focusable="true" says that this view should be focusable, while


android:focusableInTouchMode="false" makes it so it’s not focusable in touch
mode. This means you can focus it when using a screen reader, but not otherwise by
touch. You do this because this parent view isn’t clickable.

Add those same two attributes to the view with ID


recipe_spice_rating_container as well. Then, build and run.

Now, when you use TalkBack on these items, it selects the heading and ratings
together, rather than traversing them separately. Note that the rating is still missing
a content description. You’ll take care of that custom view in Chapter 10, “Robust”.

Screenshot of nacho rating and header selected together.

Allowing All Screen Orientations


It may come as a surprise that supporting both portrait and landscape in your app
makes it more accessible.

Success Criterion 1.3.4 Orientation: Content doesn’t restrict its view and
operation to a single display orientation, such as portrait or landscape, unless
a specific display orientation is essential.

Level AA

Imagine having your device mounted and not being able to change the orientation.
For example, you could have a motor disability and have your phone mounted to a
wheelchair or you could have it mounted to the dashboard of your car. Imagine your
navigation app not rotating to match the orientation of the device. This makes the
app much more difficult to use.

raywenderlich.com 78
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Right now, Taco Tuesday’s configuration locks it in portrait. To allow rotation, head
to AndroidManifest.xml.

On both the OnboardingActivity and MainActivity, delete the


android:screenOrientation="portrait" attribute.

Build and run. You can now rotate the device and see the contents rotate as well.
Most of the screens even look okay! The exception is the Discover view. The cards are
way too tall for the screen.

Note: Make sure you enable the Auto-rotate option on your device to be able
to change screen orientation.

Screenshot of discover screen in landscape with card partially hidden.


Create a new dimens.xml for landscape. It should be at app/src/main/res/values-
land/dimens.xml.

Override the following dimensions in this new file:

<dimen name="discover_card_width">424dp</dimen>
<dimen name="discover_card_height">230dp</dimen>

raywenderlich.com 79
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

This changes the card width and height for landscape mode. Build and run to see the
improvements.

Screenshot of discover screen in landscape with card fully in view.


Great, now the card looks good regardless of your device’s orientation.

Labeling Inputs
Inputs are a place for potential confusion. When working with them, it’s important
to make it clear what the input does.

Success Criterion 1.3.5 Identify Input Purpose: The purpose of each input
field collecting information about the user can be programmatically
determined.

Level AA

On the bottom of the details screen of a saved recipe, there’s a place to add notes.

Screenshot of notes field.

raywenderlich.com 80
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Right now, the Notes label is a separate TextView from the input field. With this
layout, you need to let the screen reader know that this is a label for the EditText.
To do this, use the labelFor attribute.

Open fragment_recipe_detail.xml and find the view with ID


recipe_detail_notes_label. This is the label for the input immediately below it.
Add the following attribute to the label:

android:labelFor="@+id/recipe_detail_notes_edit_text"

Build and run the app. Now, turn TalkBack on and select the EditText. It reads “Edit
box for notes”, where before it wouldn’t describe what the edit box was for.

Using a View to Describe Input


There’s another way to accomplish this: using TextInputLayout. Start by deleting
the TextView that serves as a label for this input. Then, surround the input with this
view:

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/recipe_detail_notes_input_layout"
style="@style/
Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/recipe_detail_hint_notes">

<com.google.android.material.textfield.TextInputEditText
... />

</com.google.android.material.textfield.TextInputLayout>

This creates a wrapping TextInputLayout. Note that it has a hint to describe what
the input is for.

raywenderlich.com 81
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Because you show and hide this view depending on the saved state, you need to
update this logic before you can run the app. Open RecipeDetailFragment.kt and
find showEditableFields() and hideEditableFields().

In showEditableFields(), delete the following lines:

recipeDetailNotesEditText.visibility = View.VISIBLE
recipeDetailNotesLabel.visibility = View.VISIBLE

And replace them with this one:

recipeDetailNotesInputLayout.visibility = View.VISIBLE

Likewise, in hideEditableFields(), delete these lines:

recipeDetailNotesEditText.visibility = View.GONE
recipeDetailNotesLabel.visibility = View.GONE

And add this one instead:

recipeDetailNotesInputLayout.visibility = View.GONE

All this does is show and hide your new TextInputLayout, rather than the separate
label and EditText.

Build and run. Not only does the input have a fancy new style, but it also helpfully
reads: Edit box, notes when using the screen reader.

Screenshot of updated notes field.

raywenderlich.com 82
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Supporting Text Scaling


As a quick detour from the Text Alternatives and Adaptable categories above, here
you have a sneak peek of Distinguishable.

Guideline 1.4 Distinguishable: Make it easier for users to see and hear
content including separating foreground from background.

While other chapters will cover most of the criteria under distinguishable, one way
to make your text easier for users to see is closely related to the layouts discussed in
this chapter.

The way you lay out your views affects whether people can still read the text when
it’s scaled.

Success Criterion 1.4.4 Resize text: Except for captions and images of text,
text can be resized without assistive technology up to 200 percent without loss
of content or functionality.

Level AA

On your device, go to Settings ‣ Accessibility and look for Font size. Depending on
your device, this could be at the root level or under Display size and text ‣ Font
size and style. Scale the font size up to Largest, then return to the Taco Tuesday
app.

You can see that all the text is now larger! This is because, when you set the font size
on all these views, you use sp for the unit: scalable pixels. If you were to use
another unit, such as dp or density pixels, they wouldn’t scale. Because of this, you
always want to use scalable pixels when defining text size.

Once you’ve taken care of that, you need to make sure your view’s height scales
correctly. You shouldn’t set a static height on your text views — otherwise, you could
have some text cut off.

raywenderlich.com 83
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Take a look at your saved recipes list. If you have a recipe with a long name, it cuts
off at the bottom.

Screenshot of scaled text, cut off.


The full name of this recipe is: “Chorizo scramble (aka Mandy’s Life-Saving Tacos)”,
but you can only see part of it. And the bottom of the last row of words is partly cut
off.

The first resolution for this is to make sure the height is wrap_content. Go to
item_try_it_recipe.xml and find the view with the ID item_recipe_title. Notice
that the height is set to 100dp? Change the height to wrap_content:

android:layout_height="wrap_content"

Now, build and run the app. The text no longer cuts off.

Screenshot of scaled text, fully displayed.


Making the height of your TextViews wrap_content scalable is the minimum you
need to do. If you need to restrict how many lines your text has, use the maxLines
attribute, along with ellipsize. Make sure you only do this with text where it’s okay
if the entirety isn’t readable.

raywenderlich.com 84
Android Accessibility by Tutorials Chapter 4: Perceivable — Layout & Labeling

Key Points
• The first thing to consider when making your app accessible is whether it’s
perceivable.

• You should provide content descriptions for any non-textual elements.

• Notating headers makes your app easier to navigate.

• By grouping related items, users can consume related information together.

• To make your app accessible, you should support all screen orientations.

• Labeling inputs makes it clear what they’re for.

• By using scalable pixels and avoiding static height text views, you allow for scaling
text.

Where to Go From Here?


You now have some foundational knowledge about what it means to make your app
perceivable. Great work! Continue thinking about how you can apply these things to
your own apps and what might be stopping your content from being perceivable.

You’ll continue this journey to make the app more perceivable in the next chapter,
where you’ll learn how to handle cues such as animation and color indicators.

raywenderlich.com 85
5 Chapter 5: Perceivable —
Time-Based Media & Cues
By Victoria Gonda

Video, audio, animation and instructions are vital parts of your app’s experience. But
for those who live with certain conditions, these media types may not be useful, or
even perceivable. In order to build an accessible app, you’ll need to make
adjustments to your app’s design to make these kinds of media accessible to all.

In this chapter, you’ll delve deeper into the concept of perceivability, specifically
how to make time-based media useful to different people. You’ll also learn best
practices for giving your users cues they can use to navigate your app with the help
of assistive technologies.

raywenderlich.com 86
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

Displaying Time-Based Media


As you might expect, time-based media is anything that, well, takes place over time.
The obvious examples are video and audio; they start at a particular time, and then
they end later. Animations also fall into this category. There is only one way to
consume these media types.

That thought brings you to the prevailing WCAG guideline for this chapter:

Guideline 1.2 Time-based Media Provide alternatives for time-based media.

There are many ways you can provide these types of media. For prerecorded audio,
you can have on-screen captions. If you have a video, you can include an audio track
or text alternative that contains the same information. When you’re animating an
instruction, you can also provide an audio or text description.

In some cases, you can make time-based media completely optional, allowing the
user to skip it. Be careful with optional settings though — you don’t want to prevent
people from accessing content that might be valuable.

Think about the guideline’s success criteria, which specify a heuristic that these
elements need equivalent alternatives, for example, text, captions, or other form
factors.

Consider this criterion:

Success Criterion 1.2.3 Audio Description or Media Alternative


(Prerecorded): An alternative for time-based media or audio description of
the prerecorded video content is provided for synchronized media, except
when the media is a media alternative for text and is clearly labeled as such.

Level A

Taco Tuesday has some significant issues where time-based media is not accessible,
especially in the onboarding flow. Once again, you’ll improve the app so that you can
learn.

Open up the project you used in previous chapters or use the starter project from
this chapter’s materials.

raywenderlich.com 87
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

Improving the Onboarding Flow


Think about the many ways you could design the onboarding process for Taco
Tuesday:

1. You could have a video that shows the different actions you can take. But without
an equivalent audio element to this video, your onboarding flow will be
inaccessible to people who cannot see the video. To address this, you can add an
audio track to the video that describes the instructions or add text for the user to
read.

2. You could have an audio track that follows some fun animations. But if the
animations don’t convey the same information that the audio does, then your
process will be inaccessible to those who can’t hear it. To make it accessible, you
need captions or other text.

3. You could already have text to accompany your time-based media, but the media
advances and the text vanishes faster than some people can read it. To make the
flow more accessible, you could add controls so that the user can manage the
pace.

While there are other options, Taco Tuesday currently suffers from the third issue. It
has instructional text and pages of animated, self-advancing instructions that run
regardless of whether the user is ready.

Build and run so you can explore this flow.

Exploring the Onboarding


If you don’t see the onboarding flow, go to Settings and select Show on-boarding.
Then close and reopen the app. You can do this anytime you want to see onboarding
again.

Show on-boarding in settings.

raywenderlich.com 88
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

Another option is to comment out these several lines in onCreate() under


MainActivity.kt to ensure onboarding always runs:

// val sharedPref =
PreferenceManager.getDefaultSharedPreferences(this)
// val showOnboarding = sharedPref.getBoolean("onboarding",
true)
// if (showOnboarding) {
OnboardingActivity.startActivity(this)
// finish()
// }

With that, you’ve enabled the onboarding flow to run every time. Remember to
uncomment it when you’re done with this chapter, so you don’t find yourself
annoyed by the constant onboarding flow!

The onboarding flow uses a pager where each page contains an image and some text.
It auto-advances after five seconds, and there are no buttons to control it.

Screenshots of onboarding views.


So if you didn’t read the description in time, you’re out of luck. No tacos for you! You
might be clever enough to discover that you can swipe to go back. But consider that
you must be physically able and curious enough to find and perform the swipe
gesture — that’s not a great user experience, even without regard for accessibility.

raywenderlich.com 89
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

Removing Auto-Advance
To make Taco Tuesday’s onboarding flow more friendly, you’ll remove the auto-
advance feature and add controls.

For this step, you’ll get to delete some code! Since the plan is to put the user in
control of when onboarding advances to the next page, you’ll remove the logic that
makes it advance.

Open OnboardingActivity.kt. In onCreate() look for a coroutines block that starts


with lifecycleScope.launch.

Delete the entire block of code:

lifecycleScope.launch(Dispatchers.IO) {
val options = resources.getStringArray(R.array.pop_up_options)
while (isActive) {
delay(5000) // 5 seconds

withContext(Dispatchers.Main) {
if (binding.onboardingPager.currentItem == NUM_PAGES - 1) {
MainActivity.startActivity(this@OnboardingActivity)
this.cancel()
} else {
binding.onboardingPager.currentItem++
}
}
}
}

This code would wait five seconds and then advance to the next page. If it was
already on the last page, it would open the MainActivity. But now it is gone.

Build and run. Use the settings so that you can view the onboarding flow. Note how
the auto-advancing feature is gone, and you have as much time as you need to view
the instructions.

Now that you’ve had fun deleting somebody else’s code, it’s your turn to add code.

raywenderlich.com 90
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

Adding Controls
In this section, you’ll implement logic that gives your user a straightforward way to
advance to the next page. First, you’ll add the layout for a Next button.

Open activity_onboarding.xml. Add the following view to the bottom of the


constraint layout:

<com.google.android.material.button.MaterialButton
android:id="@+id/onboarding_next_button"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/space_normal"
android:text="@string/onboarding_next"
android:textColor="?colorOnPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />

This code adds a Next button to the bottom of the screen.

But now the pager might overlap the button. So you need to replace this attribute on
the ViewPager2:

app:layout_constraintBottom_toBottomOf="parent"

With this one:

app:layout_constraintBottom_toTopOf="@id/onboarding_next_button"

This constrains the pager to the top of the Next button. Build and run, or just look at
the Design view to see what it looks like.

Next button.
Now you need a click listener for this button.

raywenderlich.com 91
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

Go back to the OnboardingActivity. At the bottom of onCreate(), add this


listener:

binding.onboardingNextButton.setOnClickListener {
if (binding.onboardingPager.currentItem == NUM_PAGES - 1) {
MainActivity.startActivity(this)
} else {
binding.onboardingPager.currentItem =
binding.onboardingPager.currentItem + 1
}
}

With this code, you’re making it so that the pager will advance when you click Next.
If you’re already on the last page, it will go to the MainActivity. Build and run to
see that everything is working as expected.

While you could stop here, you’d be depriving people of the ability to go back in the
onboarding flow. You’ll add a Back button to improve the experience.

Return to activity_onboarding.xml. Add the following code:

<com.google.android.material.button.MaterialButton
android:id="@+id/onboarding_back_button"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/space_normal"
android:text="@string/onboarding_back"
android:textColor="?colorOnPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />

This adds a Back button to the layout.

Now, you need to connect a listener.

Add the following to the bottom of onCreate() in the OnboardingActivity:

binding.onboardingBackButton.setOnClickListener {
binding.onboardingPager.currentItem =
binding.onboardingPager.currentItem - 1
}

Now the Back button will return to the previous page.

But what if you’re on the first page? Your new Back button would probably crash the
pager because there is no previous page. You should hide this button on the first
page.

raywenderlich.com 92
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

And when you’re on the last page, the Next button doesn’t make sense. It should
have text that describes what it actually does.

You can address both issues with a listener that hides the Back button when you’re
on the first page and changes the text for the Next button on the last page.

In onCreate(), add the following alongside your other listeners:

binding.onboardingPager.registerOnPageChangeCallback(
object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
binding.onboardingNextButton.text =
if (position == NUM_PAGES - 1) {
getString(R.string.onboarding_done)
} else {
getString(R.string.onboarding_next)
}
binding.onboardingBackButton.visibility =
if (position == 0) {
View.GONE
} else {
View.VISIBLE
}
}
}
)

This new listener registers an OnPageChangeCallback to monitor for page changes.


When the page does change, it sets the onboardingNextButton button text to Done
if the user is on the last page and to Next otherwise. Additionally, when the user is
on the first page, it hides the onboardingBackButton button.

Build and run. Open up the onboarding flow and notice how the buttons change as
you flip back and forth between pages.

Screenshots of all button states.


You just played around with some buttons, and now Taco Tuesday onboarding is far
more perceivable than it was. Good work!

Next up, you’ll learn about other improvements you can make with cues.

raywenderlich.com 93
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

Giving Cues
Another important part of onboarding is what you’re saying. How do you make sure
your instructions are meaningful? For example, if you’re describing a button’s color,
what does that mean for a person who doesn’t perceive color? This brings you to the
second criterion you’ll explore in this chapter:

Success Criterion 1.3.3 Sensory Characteristics: Instructions provided for


understanding and operating content do not rely solely on sensory
characteristics of components such as shape, color, size, visual location,
orientation, or sound.

Level A

While attributes such as colors and shapes can be used, you should not rely on them
to draft quality cues.

Imagine if the buttons on the discover screen to thumbs-up or thumbs-down a recipe


were green and red circles, respectively. The screen reader says, “Tap the green
button to save this recipe”. But you can’t see color well, so now you’re terrified to tap
any button because you really want those tacos but don’t know how to save the
recipe.

Grayscale buttons.
You might be thinking that giving the buttons a distinct shape would address the
issue. Then the reader would say, “Tap the green triangle to save this recipe”.
Unfortunately, calling out a shape won’t help people with severe vision impairments.

Now you’re starting to understand why this criterion exists!

raywenderlich.com 94
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

You may have noticed the ambiguous directions in the pager: “Orange to the right,
tacos in sight”!

Orange what? What if you can’t see orange? What if you also can’t see the image to
give you a hint about what this means?

Clearly, Taco Tuesday’s onboarding is not meeting success criterion 1.3.3. That’s
fortunate for you because you’ll get to make it better and learn a few things along
the way.

Improving Cues in Onboarding


There are several things you’ll do to improve the onboarding flow’s cues. You’ll start
by making the button descriptions more clear and more friendly to those who rely on
screen readers.

Clarifying the Instructions


The instructions are defined in strings.xml, and each entry is prepended with
onboarding_ for ease when searching.

You’ll rewrite the first three instructions.

The first is “Orange to the right, tacos in sight”! This instruction means to say that
you should swipe the orange card to the right to save it. You need the description to
be more specific and less poetic.

Replace the onboarding_try_it value with: Swipe the orange recipe card to
the right to save it to try later.

You can follow the same logic to replace the instruction “Orange to the left, move on
to the rest”.

Replace the string named onboarding_discard with: Swipe the orange recipe
card to the left to say \"no thank you!\" to a recipe.

Finally, the third instruction reads: “Green is keen to lead the way”. This gives little
information at all!

Replace the value of onboarding_view_list to be: Then, you can view the list
of recipes you want to try.

Your new instructions are much more descriptive, but you’re going to improve them
further!

raywenderlich.com 95
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

Remember that some people are not able to swipe. And the instructions don’t inform
the reader they can save a recipe from the detail screen.

Run the app and notice where the button shown below is and what it looks like. Look
for it in the details view — you can get there by clicking the view icon from the
discover screen or the list of saved recipes.

Icon buttons on the detail screen.


How would you describe this button? Your description can’t rely on color or shape,
nor can it use a visual location. It doesn’t have text, so you can’t use that either. A
combination of these would be an improvement but not a full fix.

Adding Text to the Button


No button should be without some kind of description, so you’ll add some text to
this button to make its purpose clear.

In the fragment_recipe_detail.xml layout, find the ImageView with the id


recipe_detail_try_discard_button. To enable text support, replace ImageView
with the following class:

com.google.android.material.button.MaterialButton

Now you’re working with a proper button where you can use a compound image with
text.

Remove the image source:

android:src="@drawable/ic_baseline_thumb_up_24"

And replace it with these attributes:

android:text="@string/shared_try_it"
app:icon="@drawable/ic_baseline_thumb_up_24"

raywenderlich.com 96
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

When you look at the Design view, this button now has some descriptive text along
with the thumbs-up icon.

Try it button.

Modifying the Button State


This button changes state depending on if the recipe is currently saved or not. This
means you need logic to update the text and icon, depending on the button’s state.

Open RecipeDetailFragment.kt and find showEditableFields() and


hideEditableFields(). These are the methods that control the view depending on
the state.

In showEditableFields(), delete this statement:

recipeDetailTryDiscardButton.setImageDrawable(
ResourcesCompat.getDrawable(resources,
R.drawable.ic_baseline_thumb_down_24,
requireContext().theme))

And replace it with these statements:

recipeDetailTryDiscardButton.text =
getString(R.string.shared_discard)
recipeDetailTryDiscardButton.icon =
ResourcesCompat.getDrawable(resources,
R.drawable.ic_baseline_thumb_down_24,
requireContext().theme)

This makes it so that when the recipe is already saved, the button gives the user the
option to discard it.

Next, for the reverse case, delete this statement from hideEditableFields():

recipeDetailTryDiscardButton.setImageDrawable(
ResourcesCompat.getDrawable(resources,
R.drawable.ic_baseline_thumb_up_24,
requireContext().theme))

And replace it with this code:

recipeDetailTryDiscardButton.text =
getString(R.string.shared_try_it)

raywenderlich.com 97
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

recipeDetailTryDiscardButton.icon =
ResourcesCompat.getDrawable(resources,
R.drawable.ic_baseline_thumb_up_24,
requireContext().theme)

Now, when a recipe is not saved, the button allows the user to save it to try later.

Build and run to see your changes.

Updated buttons on the detail screen.

Adding State-Specific Instructions


Now you can add instructions for this button to your onboarding. You’ll need to add
a new page just for these instructions.

First, you need to write and add the message. In strings.xml, add the following line:

<string name="onboarding_details">Manage your recipes using the


\"Try it\" and \"Discard\" buttons on the detail view.</string>

Then, add the new image resource to the project. Look for it in this chapter’s
materials assets ▸ onboarding_details.xml. Add this new image to the drawable
folder of this project.

You also need a content description for your image if you chose to add it during the
challenge in Chapter 2, “Hello, Accessibility”.

Add the following to strings.xml:

<string name="onboarding_details_description">Thumbs-up icon</


string>

Now, you can show your new onboarding page.

Go to OnboardingActivity.kt and find the companion object with the pages list.
Add the following to the list of pages right after the onboarding_discard item:

OnboardingItem(
R.drawable.onboarding_details,

raywenderlich.com 98
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

R.string.onboarding_details,
R.string.onboarding_details_description
),

Finally, update NUM_PAGES to use a computed getter, so it always has the correct
number of pages:

private val NUM_PAGES: Int


get() = pages.size

Build and run to see your new onboarding page. And enjoy how much more
accessible your onboarding is!

Screenshot of new onboarding page.

raywenderlich.com 99
Android Accessibility by Tutorials Chapter 5: Perceivable — Time-Based Media & Cues

Key Points
• Time-based media such as video, audio and animations, must be accompanied by
alternatives.

• Alternatives to visual media can be text or audio, and alternatives to audio can be
equivalent visuals.

• Users must be able to control media that’s important for them to understand. You
need to provide a way for them to go back and revisit something

• Sensory characteristics such as shape, color, size, visual location, orientation or


sound should not be the only ways you give instructions.

Where to Go From Here?


Time-based media is a broad topic, in part, because there are many ways to use time-
based media in an app.

When you’re unsure how to handle something, remember to lean on the WCAG,
which offers ideas in addition to guidance: https://www.w3.org/TR/WCAG21/#time-
based-media

When you’re ready to move on, you’ll finish up this three-chapter series about
perceivability in the next chapter by digging into colors.

raywenderlich.com 100
6 Chapter 6: Perceivable —
Colors
By Victoria Gonda

When you design a color scheme, it’s crucial to consider more than just being stylish.
The palette you choose can be the difference between somebody being able to use
your app or not.

This is the last chapter that will focus on the perceivable concept in this book. You’ll
explore tactics to help you meet this guideline from WCAG:

Guideline 1.4 Distinguishable: Make it easier for users to see and hear
content including separating foreground from background.

Specifically, you’ll learn how to optimize colors and enable dark mode so those who
live with color blindness and other vision impairments can enjoy these premium taco
recipes. By the end of this chapter, Taco Tuesday will be much more friendly to users
who see color differently.

raywenderlich.com 101
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

Measuring Color Contrast


Color contrast is the difference in lightness between two colors. Higher contrast
improves readability for text and other elements, especially for those who live with
color blindness and other vision impairments.

One way to think of it is to imagine your app under a grayscale filter. How
distinguishable would the grays be? The more different they are, the more contrast
your colors have.

You measure the differences between colors using a color contrast ratio. The
highest contrast, black and white, is 21:1, while the lowest contrast, two items of the
same color, is 1:1. Don’t worry, you don’t have to learn any tricky equations. You’ll
use tools to measure contrast.

WCAG has laid out specific contrast ratios in Success Criterion 1.4.3:

Success Criterion 1.4.3 Contrast (Minimum): The visual presentation of


text and images of text has a contrast ratio of at least 4.5:1, except for the
following:

· Large Text: Large-scale text and images of large-scale text have a contrast
ratio of at least 3:1

· Incidental: Text or images of text that are part of an inactive user interface
component, that are pure decoration, that are not visible to anyone, or that are
part of a picture that contains significant other visual content, have no
contrast requirement.

· Logotypes: Text that is part of a logo or brand name has no contrast


requirement.

Level AA

There are several details to unpack over the next several pages:

• The base rule

• Large text

• Different levels of compliance

• Which elements are not subject to this guidance

raywenderlich.com 102
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

Understanding Color Contrast


The base rule says that text and text images need to have a ratio of at least 4.5:1.

Search online for a color contrast calculator to run some experiments. Play with
different palettes until you find a contrast ratio close to 4.5:1. One example to try is
the color combo #767676 and #FFFFFF.

Text with a 4.5:1 ratio.

Note: At the time of writing, this checker form WebAIM (https://webaim.org/


resources/contrastchecker/) was reliable.

For larger text, the minimum ratio of 3.1 is lower than for the main text. Why is this?
What is considered large text?

Bigger text is easier to read, and “large” is somewhat subjective. In general, you can
follow the rule that 18sp regular text or 14sp bold text is sufficient to fall under the
guidance for “large text”.

Use your contrast checker tool to see how a 3:1 ratio looks. An example is #949494
compared to #FFFFFF.

Large text with a 3:1 ratio.


Success Criterion 1.4.6 Contrast (Enhanced) prescribes ratios of 7:1 for regular text
and 4.5:1 for large text, which is AAA level compliance. You’ve already looked at
4.5:1. Now see what 7:1 looks like. Try out the hex codes #595959 and #FFFFFF.

Text with a 7:1 ratio.

raywenderlich.com 103
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

Now turn your attention to the elements you can exclude from these requirements —
reference the last two bullet points on Success Criterion 1.4.3. You’ll see that
incidental items are excluded. These include decorative text, disabled buttons and
hidden elements.

If you decide an element can use low-contrast colors, make sure the user has all the
information they need if they can’t see it. For example, toggle the enabled attribute
on a button so the accessibility services understand this button’s state.

Logos and brand names are also excluded. You can decide if you need to adjust them
so that they are visible.

Now that you know what this guideline means, you have the context to dig into the
vision impairments that inspired these guidelines.

Understanding Vision Impairments


Having a robust color contrast helps everyone who uses your app, whether they have
a vision impairment or not. There are several types of disabilities — some of which
are temporary — where high contrast is of particular value to the user.

When making tacos in bright conditions: Think about how hard it can be to see
your screen in the sun. High contrast ratios improve the user experience in bright
conditions.

When your device is at a distance: If you’re looking at your phone from a distance,
maybe because your hands are full of taco ingredients, you’ll comprehend more of
the content at a distance when the contrast ratios are higher.

When your glasses are MIA: Don’t forget about those who remove their glasses or
contacts before bed. If they wanted to review taco recipes while in bed, a high color
contrast means they may be able to see without those glasses or contacts.

When you live with a vision impairment: Some impairments make parts of a
person’s vision blurry or dark. Some cause floaters, while others bring double-vision.
Each impairment manifests with varying levels of severity. Higher contrast makes it
easier for many people who live with these, and other impairments, to see your taco
recipes.

raywenderlich.com 104
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

Grid showing a simulation of different vision impairments.


Do you now understand how improved contrast can help people?

raywenderlich.com 105
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

Exercise: Explore how these impairments affect someone’s vision with


simulators.

Are you curious how it feels to live with vision impairments? Browser plugins
can help you get a glimpse into life for some of your users. The NoCoffee
Chrome Extension created the above simulations.

Try it for yourself. Search for a vision simulator for your favorite browser to
experience these changes.

Remember that these simulations won’t capture the full experience of living
with a vision impairment. The nature of the impairment, severity and length
of time a person has lived with a vision issue affects how the user interacts
with the world. Simulators simply help you put yourself in your user’s shoes so
that you can do better when making your apps accessible.

Simulating Color Blindness


Color blindness means that you don’t see some or all colors fully. For example, reds
and greens can look quite similar. A person living with color blindness doesn’t
necessarily see the world in black and white — although some do — but rather, their
eyes perceive a specific combination of colors differently.

For these cases, the relative lightness in color is essential.

Android devices provide a way to simulate color blindness. Turn it on now by going
to Settings ▸ Developer options ▸ Simulate color space. You can find it under
Hardware accelerated rendering or just search for it.

Note: For help with the developer settings, go back to Chapter 3, “Testing &
Tools”.

raywenderlich.com 106
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

Here, you’ll find several different options. Try a couple of them to simulate color
blindness and note the color changes in different apps. Make sure you try
Monochromacy to see what your apps look like in full grayscale.

Simulate color space dialog.


Did you spot any views that might benefit from increased color contrast?

Open the project you used for the previous chapter, or get the starter project from
this chapter’s materials.

Disable the color blindness simulations then build and run.

Taco Tuesday’s home screen.

raywenderlich.com 107
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

Detecting Low Contrast


Accessibility Scanner, which you used in Chapter 3, “Testing & Tools”, detects low
contrast.

Turn it on in Settings ▸ Accessibility ▸ Accessibility Scanner. Open Taco Tuesday


and scan the main screens.

Text contrast results.


Review any suggestion labeled Text contrast.

In these suggestions, you’ll see your existing contrast, as well as the contrast needed
to meet guidelines. Use these hints to inform decisions about the palette.

If the suggestion is about a decorative text element, you can leave it alone because
it’s acceptable to inform the accessibility services to ignore it. If it’s large text and
the scanner doesn’t detect that, it’s also OK to leave it.

As you can see from the suggestions, you have some fixes to make. In a few more
paragraphs, you’ll get to make those changes.

raywenderlich.com 108
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

Improving Color Contrast


Most color contrast issues in Taco Tuesday happen where the orange accents are
paired with white. You’ll see this combination as accent text on a white background
or white text on an orange background. The contrast ratio between these two colors
is 4.15:1.

The Level AA guidance specifies that 4.5:1 should be the minimum text contrast.
How do you implement this guideline? You have some options:

• Use a different color from your design system.

• Add a new color.

• Update your color palette.

Contrast issues are less burdensome to tackle when your app is young or undergoing
a redesign. In both cases, you have the flexibility to change the design system or
color palette, which are the most efficient ways to modify colors across an app.

For Taco Tuesday, which is a young app, you’ll change the color palette. Specifically,
you’ll change the orange accent to another orange with a higher contrast ratio to
white.

Note: How can you find more accessible colors? The most straightforward way
is to play around with different colors in a contrast checker or use an online
tool to find an alternate color similar to your existing color.

If your team has a designer, you should consult with them. What you consider
a minor change could “break” a color scheme.

Accessible Color Generator (https://learnui.design/tools/accessible-color-


generator.html) generated the colors for this chapter. You can also search for
an accessible color generator online to find alternatives.

raywenderlich.com 109
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

Updating the Palette


Open colors.xml and notice that the accent color is #c75f00. Using a color
generator of your choice, compare #c75f00 to white, #FFFFFF. You’ll get a
suggestion, possibly #bf5800. Recommendations will vary across color generators.

In colors.xml, replace the value for colorAccent with the suggested color. Append
the alpha value FF to the start of the hex code because some places in the app
require it:

<color name="colorAccent">#FFbf5800</color>

Build and run, then scan the same places that triggered the contrast suggestions. You
should see no more suggestions!

No suggestions.

Implementing Next-Level Compliance


Right now, Taco Tuesday is cruising along at Level AA compliance. The scanner helps
you conform to Level AA, but sometimes 4.5:1 isn’t enough. Sometimes you need
Level AAA compliance, which is 7:1. Taco Tuesday isn’t there yet, so you’re going to
make more changes.

Your new contrast for the orange accent color, #bf5800on white is 4.55:1, and the
primary green color, #006837 with white is 6.91:1.

Go to colors.xml. Change the primary color to #006635 and the accent color to
#FF983800:

<color name="colorPrimary">#006635</color>
<color name="colorAccent">#FF983800</color>

raywenderlich.com 110
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

Build and run. Depending on how well you distinguish color, you might notice that
the new accent color is much darker. It now meets the color contrast requirements
for text for Level AAA!

Side by side color comparison.

Handling Non-Text Contrast


Text isn’t the only element that people consume in an app, so it’s not the only type
of view that is subject to WCAG’s contrast guidance. Take a look at this criterion:

Success Criterion 1.4.11 Non-text Contrast: The visual presentation of the


following have a contrast ratio of at least 3:1 against adjacent color(s):

· User Interface Components: Visual information required to identify user


interface components and states, except for inactive components or where the
appearance of the component is determined by the user agent and not
modified by the author;

· Graphical Objects: Parts of graphics required to understand the content,


except when a particular presentation of graphics is essential to the
information being conveyed.

Level AA

raywenderlich.com 111
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

The short version of this criterion is that, if you have a view that the user needs to
perceive, understand and use, it needs a contrast ratio of at least 3:1.

Image buttons and icons fall into this category!

Increasing Button Contrast


Go to the list of saved recipes and run the Accessibility Scanner.

Image contrast result.


Look for a suggestion for the View Details button. It has a 2.11:1 ratio, far short of
the suggested ratio of 3:1. You can fix the contrast by making the button white to
match the text on the card.

Open item_try_it_recipe.xml and find the view with the ID item_recipe_details.


Add the following attribute to the ImageView:

app:tint="?colorOnPrimary"

raywenderlich.com 112
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

The ?colorOnPrimary value is the same white as the text uses. The reason you’re
using semantic names like “colorOnPrimary” rather than color names like “white”
will become apparent soon enough. Until then, build and run to see your changes.

Image button with strong contrast.


For now, you can ignore the suggestion that says the button is too small — the
contrast is now acceptable, and this task is done.

Introducing Dark Mode


Did you know that dark mode is an accessibility feature?

“A dark theme is a low-light UI that displays mostly dark surfaces”, according to


Android’s Material Design guidelines.

While using dark mode is more commonly thought of as a style preference, for some
people, it can be the difference between being able to use an app or not.

Consider if you lived with floaters in your vision, for example. They float around,
obstructing your vision wherever they are. How frustrating that could be.

It turns out that, typically, floaters are more visible on a bright background, so
choosing a dark background improves the experience for many who live with this
condition.

Light and dark mode screens with floaters simulation.


Next up, you’ll set up Taco Tuesday to support dark mode.

raywenderlich.com 113
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

Adding Support for Dark Mode


Lucky for you, Taco Tuesday uses semantic names for all the colors, so you only need
to provide colors for the dark theme and enable it.

Start by creating a file to hold your dark theme colors:

1. In Android Studio’s Project pane, select the Project tab.

2. Then create colors.xml in app/src/main/res/values-night.

Note the values-night part of the file path, which specifies that this is for the
“night” configuration. If the project doesn’t contain the values-night directory,
create it.

Add this content to the file:

<?xml version="1.0" encoding="utf-8"?>


<resources>
<color name="colorPrimary">#52a871</color>
<color name="colorAccent">#FFe6782a</color>
</resources>

With this, you’re overriding the primary and accent colors.

These colors already meet accessibility guidelines for color contrast. The Material
theme handles all the other colors.

Next, you’ll instruct the theme to allow dark mode.

1. Open styles.xml and find the AppTheme style.

2. Change the value of the parent attribute to the following:

Theme.MaterialComponents.DayNight.NoActionBar

This DayNight theme knows how to handle dark mode for elements such as text and
backgrounds.

Finally, you need a way to turn night mode on and off. You’ll set it so that the app
follows the device’s system settings.

Open TacoTuesdayApp.kt and override onCreate() with the following code:

override fun onCreate() {


super.onCreate()
AppCompatDelegate.setDefaultNightMode(

raywenderlich.com 114
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
}

Now, Taco Tuesday will use whatever theme the user has chosen.

It’s essential to provide a way to turn dark mode on and off. For some users, dark
mode makes things harder. Defaulting to the device settings is the best way to
support it.

If you have Android 10 or higher, go to Settings ▸ Display or Settings ▸


Accessibility ▸ Dark theme to turn on dark mode.

Then, build and run to see Taco Tuesday in dark mode.

Dark mode screenshots.


Congratulations! Taco Tuesday’s colors now meet WCAG accessibility guidelines, and
these fantastic taco recipes are easier to read and understand.

Selecting Dark Mode Colors


One last note about choosing dark mode colors for your app: While black text on a
white background is the most readable for a light theme, the reverse is not true for a
dark theme.

Pure white text on a pure black background can be too harsh, especially for users
with astigmatisms, which involve deformed lenses in the eyes. A slightly softer
contrast of light text on a dark background is better for everybody.

raywenderlich.com 115
Android Accessibility by Tutorials Chapter 6: Perceivable — Colors

Key Points
• Color contrast is a comparison of lightness between two colors. It’s expressed as a
ratio, with 21:1 being the highest and 1:1 the lowest.

• A higher color contrast makes your app easier to perceive, while lower contrast
makes it more difficult.

• Level AA guidelines call for a text color ratio of 4.5:1 and a large text ratio of at
least 3:1.

• Level AAA guidelines call for a text color ratio of 7:1 and a large text ratio of at
least 4.5:1.

• Non-text elements, such as button icons, must have a ratio of at least 3:1.

• Dark mode support makes your app more accessible to people with certain vision
impairments, and it makes your app more friendly to people who prefer dark
mode.

Where to Go From Here?


In the next chapter, you’ll start looking at the category Operable.

Before moving on, you should look at the full WCAG: Perceivable (https://
www.w3.org/TR/WCAG21/#perceivable) list to get an overview of additional topics
you’ll want to study further.

When you’re done with that, please proceed full steam ahead to the next chapter!

raywenderlich.com 116
7 Chapter 7: Operable —
Navigating the Screen
By Victoria Gonda

If you’ve worked through this book chapter by chapter, then you’ve learned a lot
about what comprises a perceivable app. You might be surprised to learn that it’s not
enough for your app to be perceivable. It also needs to be operable, which is defined
by the WCAG as:

2. Operable: User interface components and navigation must be operable.

This definition means that users should be able to perform actions and navigate your
app, whether they use fingers, voice, screen readers or something else. Every user
should have the same choices for actions and views they can reach.

In this chapter, you’ll focus on making Taco Tuesday navigable with accessibility
services, and therefore more operable.

raywenderlich.com 117
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

Traversing Using a Keyboard


There are multiple ways to navigate an Android device with a keyboard. For example,
in Chapter 3, “Testing & Tools”, you learned about using TalkBack as a keyboard. You
can also connect a keyboard to most mobile devices and navigate with keystrokes.
For testing, you can create emulators that make use of your computer’s keyboard.

To navigate with a keyboard, you use the Tab and Arrow keys. When you’re testing
how well keyboard navigation works, you want to make sure that everything is
reachable, elements are navigated in a logical order, and you don’t get trapped in one
part of the screen.

WCAG’s guideline for keyboards is straightforward:

Guideline 2.1 Keyboard Accessible: Make all functionality available from a


keyboard.

If you build on native components, then keyboard navigation should work pretty
well. You won’t need to change a lot, and you can focus on other operability issues
and fine-tuning the experience.

Adjusting Navigation Order


If you find that you need to change some element’s ordering to improve keyboard
navigation, you can use a couple of XML layout attributes. Here’s the first:

android:nextFocusForward="@+id/editText1"

You use nextFocusForward to instruct the view where to go next when the user
presses Tab or next. It says that when you’re on this view and navigate to the next
view, the view with the ID editText1 will be next.

raywenderlich.com 118
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

For arrow key navigation, you need these:

android:nextFocusUp="@+id/editText1"
android:nextFocusDown="@+id/editText2"
android:nextFocusLeft="@+id/editText3"
android:nextFocusRight="@+id/editText4"

These attributes tell the view where to take you when you press a directional arrow
key.

Note: To learn more about keyboard navigation on Android, go to the official


documentation (https://developer.android.com/training/keyboard-input/
navigation).

Navigating Your App


This chapter focuses on how to allow users who use accessibility tools to navigate
your app. WCAG’s guideline is logical but broad:

Guideline 2.4 Navigable: Provide ways to help users navigate, find content,
and determine where they are.

There’s a lot to unpack for this guideline, and this chapter can only cover so much, so
you’re going to dive right into the first use case: people who use screen readers to
discover content and determine where they are.

Distinguishing List Items


As you know from earlier in the book, content descriptions are important. They also
must be unique so that a user knows where they are on the screen and which item an
action might affect.

raywenderlich.com 119
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

Lists often need special attention to ensure operability.

Build and run. Go to your saved recipes and scan the screen with the Accessibility
Scanner. You should get this suggestion back: “Item descriptions: Multiple items
have the same description.”

Multiple items have the same description.


When someone uses a screen reader, it should be clear which elements go with which
items. For example, a checkbox description, such as Made recipe, should be
attributed to the correct recipe.

Improving Content Descriptions


Open TryItRecipesRecyclerViewAdapter.kt. In ViewHolder, find bind(). Here is
where you’ll add all your content descriptions.

You probably noticed that three views in the list items are ambiguous:

1. The Made it checkbox

2. The view details button

3. The nacho-based rating display

When you use a screen reader and reach one of these elements, it’s not always clear
to which recipe it pertains. A simple fix is to add the recipe name to the content
description.

raywenderlich.com 120
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

For now, you’ll just improve the checkbox and the view details button, and you’ll
save the third view for “Chapter 10, Robust”.

In bind(), add the following:

binding.itemRecipeMade.contentDescription =
itemView.context.getString(
R.string.try_it_description_made_recipe, recipe.name)

binding.itemRecipeDetails.contentDescription =
itemView.context.getString(
R.string.try_it_description_details_recipe, recipe.name)

Now, when you reach a recipe you’ve marked as made in the recipe list, it will say
“Made <recipe name>” instead of “Made it”. Similarly, when you reach the view
details button, the screen reader says, “<recipe name> details.”

Build and run.

Run the Accessibility Scanner on this view to confirm you resolved the suggestions.
Then, turn on TalkBack and observe the output when you reach these views.

TalkBack output with unique descriptions.

Keeping List Item Focus


Focus items have similar requirements. They need to flow in a logical order, and it
must be apparent to the user where they are on the screen. It’s also acceptable, if not
advisable, to skip duplicated content.

raywenderlich.com 121
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

Here’s the WCAG success criterion for focus ordering:

Success Criterion 2.4.3 Focus Order: If a web page can be navigated


sequentially and the navigation sequences affect meaning or operation,
focusable components receive focus in an order that preserves meaning and
operability.

Level A

Taco Tuesday conveniently has a related bug: when you mark a recipe as made on
the list view using TalkBack, the list will lose focus. This behavior could confuse or
frustrate users when they are transported to another part of the screen (or on newer
operating systems, when the list flashes deselected).

Try it for yourself:

1. Make sure you have a couple of recipes saved.

2. Turn on TalkBack, and try to mark a recipe from the list view as made.

3. See how you jump away?

TalkBack focus before and after checking the box.


The jump happens when you change the data that’s backing the view. You need to
address this issue when you allow users to perform actions on list items that change
the underlying data.

A known bug (https://issuetracker.google.com/issues/37088814) in RecyclerView


item animator, which exists at the time of writing, causes this behavior. The best way
to resolve it is a workaround.

raywenderlich.com 122
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

Resolving the List Item Focus Bug


First, disable the item animator:

1. Open TryItRecipesFragment.kt.

2. In onCreateView() find the with(binding.root) block that configures the


RecyclerView.

3. In that block, add the following line:

itemAnimator = null

This line sets the item animator to null. If you’re using adapter.notifyItem*()
when changing items, this is all you need to do.

Yes, this solution has a downside. Alternatively, you could make animations optional
so people who want animations can have them, and people using a screen reader can
skip them.

Taco Tuesday submits the full list when it changes, so there is another step: You
need to use stable IDs.

Open TryItRecipesRecyclerViewAdapter.kt. Add the following init block to


TryItRecipesRecyclerViewAdapter.

init {
setHasStableIds(true)
}

This init states that the RecyclerView uses stable IDs. Since you’re saying this, you
also need to define those IDs.

Override the following method in the same class:

override fun getItemId(position: Int): Long {


return getItem(position).id
}

This block uses the id of the recipe as the stable ID.

raywenderlich.com 123
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

Build and run. Use TalkBack again. When you toggle the checkbox, the focus should
stay on that item.

TalkBack focus before and after checking the box.


Now it’s much easier for users running TalkBack to mark recipes as made.

Managing Links
Links are common in apps, especially when displaying user-generated content.
Because of this, there are criteria for addressing links. Here’s one of them:

Success Criterion 2.4.4 Link Purpose (In Context): The purpose of each link
can be determined from the link text alone or from the link text together with
its programmatically determined link context, except where the purpose of the
link would be ambiguous to users in general.

Level A

This rule applies to links that are in line with other content.

When you make the link text understandable, you make it easier for the user to
decide if they should click it. You also allow people using screen readers to view all
the links on a page and intentionally navigate to them.

There are many ways to contextualize a link:

• Add context right before or in the link text itself.

• Include the title of the link.

• Include a description of the contents.

• Specify the purpose of the link.

raywenderlich.com 124
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

Exploring Links in Taco Tuesday


Take a look at a detailed view of a recipe. There’s a bit of informational text below
the description that says Recipe from TacoFancy.

Recipe from TacoFancy.


Here, TacoFancy is a hard-coded link. The link text is the title of the page, so the
link’s purpose is fairly straightforward.

But consider how messy links will get when people add user-generated content. It’s
much harder to control what you can’t foresee.

Experience this issue for yourself:

1. Find a recipe with a description containing links.

2. Turn on TalkBack.

3. Select that view.

4. Then either swipe up and to the right, or use press Alt + Shift + Space to open
the local context menu.

5. Select Links to see the full list of links.

TalkBack links menu.

raywenderlich.com 125
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

It’s not always clear where you’ll navigate to when you open these links.

You don’t need to edit the user’s content. It’s OK to display it as-is, but you can also
make improvements.

Improving the Experience Around Links


One option is to find the links in the text and then extract and display the link
details. You see this in many apps. For example, Twitter shows link previews.

Tweet with link preview.


Another option is to use a custom span to inform the accessibility services about
extra link data. With this option, you tell the services to read the full URL. Although
it’s not the best experience for Taco Tuesday, you’ll learn about TtsSpan, which will
be useful in other cases.

TtsSpan is a Span that can provide metadata to text-to-speech engines such as


TalkBack. You can use it to improve the experience when these engines encounter
text containing dates, times, money, websites and more.

For example, when you use it for the date “02/02/2020”, it will read “Sunday the
second of February 2020” instead of “02 slash 02 slash 2020”.

Unfortunately, not all Android devices have text-to-speech engines that use the
metadata provided by TtsSpan. You’ll add this improvement for those who have
devices supporting this feature.

Implementing TtsSpan
You’ll use TtsSpan as a custom Span for your markdown links.

Open RecipeDetailFragment.kt and find getMarkwon(), the code that lets you
customize the configuration for the markdown parser, Markwon, via plugins.

raywenderlich.com 126
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

You’ll see the below plugin that modifies the link text color — delete it:

.usePlugin(object : AbstractMarkwonPlugin() {
override fun configureTheme(builder: MarkwonTheme.Builder) {
builder.linkColor(ContextCompat.getColor(requireContext(),
R.color.colorPrimary))
}
})

Now you can replace it with a new plugin, which will still modify the link color.

Add a new, empty plugin by adding this code where you deleted the previous plugin:

.usePlugin(object : AbstractMarkwonPlugin() {
override fun configureSpansFactory(
builder: MarkwonSpansFactory.Builder
) {
super.configureSpansFactory(
builder.setFactory(Link::class.java,
object : LinkSpanFactory() {
override fun getSpans(
configuration: MarkwonConfiguration,
props: RenderProps
): Any {

}
})
)
}
})

This boilerplate code creates the AbstractMarkwonPlugin that Markwon will use
while parsing your markdown. In that anonymous class, you are overriding
configureSpansFactory() to set a custom Span factory for Link items.

Right now, it won’t compile because you need to return something.

An example of an acceptable return type is a list of Span items. You’ll return your
TtsSpan, a LinkSpan, so the system knows to treat it as a link, and a
ForegroundColorSpan to make sure you’re matching your theme.

You need the link information before you build a Span.

Add this to the top of getSpans():

val href = CoreProps.LINK_DESTINATION.require(props)


val uri = Uri.parse(href)

raywenderlich.com 127
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

These lines get the href of the link and parse it into a Uri, so you get the different
parts of the link.

Next, add the following to the bottom of getSpans():

return arrayOf<Any>(

This provides a place to return Spans.

Next, add the LinkSpan and the ForegroundColorSpan to the list to preserve the
existing behavior:

LinkSpan(configuration.theme(), href,
configuration.linkResolver()),
ForegroundColorSpan(ContextCompat.getColor(requireContext(),
R.color.colorPrimary)),

Here you add a LinkSpan for link behavior. Because this is a Markwon Span, you pass
along the existing Markwon metadata. You also add a ForegroundColorSpan to
make sure the link uses your primary color.

Finally, the moment you’ve been waiting for: add your TtsSpan to the bottom of the
list and build:

TtsSpan.ElectronicBuilder()
.setPort(uri.port)
.setDomain(uri.host)
.setPath(uri.path)
.setQueryString(uri.query)
.build()

Each type that TtsSpan supports has a builder, and you use a builder to define each
part of the link. Specifically, you use the ElectronicBuilder to set the port,
domain, path, and query.

Build and run with TalkBack on. Go to the details screen for a recipe. Swipe up and to
the right to show the context menu.

When you select links, TalkBack should read the entire URL rather than just the text
displayed to sighted users.

Note: If you’re not hearing the link read aloud, your device might not have a
text-to-speech engine that consumes the metadata TtsSpan provides.

raywenderlich.com 128
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

Handling Gestures
Support for gestures gives an app a layer of polish — allowing your users to swipe or
pinch to perform actions can bring delight.

Unfortunately, you can create accessibility issues when a gesture is the only way to
perform a particular action.

Success Criterion 2.5.1 Pointer Gestures: All functionality that uses


multipoint or path-based gestures for operation can be operated with a single
pointer without a path-based gesture, unless a multipoint or path-based
gesture is essential.

Level A

Simply put, this criterion specifies that any action that you can perform using
multiple fingers or a drag of a finger must also have a single-tap-based alternative.

You might have noticed a related issue in Taco Tuesday’s recipe list: You can swipe
to discard a recipe, but swiping is the only way to discard a recipe.

You’ll implement two different options to further improve the app’s accessibility.

Adding Long Press to Discard


The first option is a long press. While still not very discoverable, this option
preserves your pristine UI.

Open TryItRecipesRecyclerViewAdapter.kt, and find bind() in the ViewHolder.


Add the following long-click listener to the method:

// 1
binding.itemRecipeTitle.setOnLongClickListener {
// 2
MaterialAlertDialogBuilder(it.context)
.setTitle(R.string.try_it_discard_confirm_title)
.setMessage(it.context.getString(
R.string.try_it_discard_confirm_message, recipe.name))
// 3
.setPositiveButton(
R.string.try_it_discard_confirm_discard) { _, _ ->
onDiscardRecipe(recipe)
}
// 4
.setNegativeButton(

raywenderlich.com 129
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

R.string.try_it_discard_confirm_cancel) { _, _ -> }
.show()
true
}

What you’re doing here is:

1. Setting up a long-click listener for the recipe title.

2. Showing a confirmation dialog when the user long clicks.

3. Discarding the recipe upon confirmation.

4. Nothing if the user cancels.

Build and run. Long press on the title of a saved recipe to see the confirmation and
delete a recipe.

Dialog to confirm discarding a recipe.

Describing Actions
Now attempt the same action with TalkBack turned on. You’ll hear “Double-tap and
hold to long-press”.

Double-tap and hold to long press.


That’s not very descriptive. In addition to content, your descriptions can provide
insights into available actions. Accessibility delegates are one tool that you can use
to create better descriptions.

Create a new file named DeleteRecipeAccessibilityDelegate.kt to create your


delegate. Add the following empty class to the file:

class DeleteRecipeAccessibilityDelegate(
private val recipeName: String

raywenderlich.com 130
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

) : AccessibilityDelegateCompat() {

Here you create DeleteRecipeAccessibilityDelegate, which inherits from


AccessibilityDelegateCompat. By overriding methods on this delegate, you
provide your action metadata.

You’re also passing in a recipe name as a constructor parameter, so you can include
that name in the description.

Next, override onInitializeAccessibilityNodeInfo() with the following body:

override fun onInitializeAccessibilityNodeInfo(


host: View,
info: AccessibilityNodeInfoCompat
) {
// 1
super.onInitializeAccessibilityNodeInfo(host, info)
// 2
val longClick =
AccessibilityNodeInfoCompat.AccessibilityActionCompat(
AccessibilityNodeInfo.ACTION_LONG_CLICK,
host.context.getString(
R.string.try_it_description_discard_recipe,
recipeName))
// 3
info.addAction(longClick)
}

Here you:

1. Call the super method.

2. Create an AccessibilityActionCompat to specify that you’re defining a long


click and description of the action.

3. Add the AccessibilityActionCompat to the AccessibilityNodeInfoCompat.

Finally, you need to set this accessibility delegate on the list item title.

Open TryItRecipesRecyclerViewAdapter.kt and find bind() where you added the


long click listener. Add this to bind():

ViewCompat.setAccessibilityDelegate(binding.itemRecipeTitle,
DeleteRecipeAccessibilityDelegate(recipe.name))

raywenderlich.com 131
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

This gives the recipe name to the accessibility delegate and sets it on the title.

Build and run. Use TalkBack again and notice that you now hear “Double-tap and
hold to discard <recipe name>.”

Double-tap and hold to discard Moroccan Lamb Tacos.

Adding a Discard Button


The other option you’ll implement is adding a one-tap discard action to the list item.
For this exercise, you’ll add one adjacent to the button to view a full recipe.

Open item_try_it_recipe.xml. Right above the view with the ID


item_recipe_details, add the following view:

<ImageButton
android:id="@+id/item_recipe_discard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:iconGravity="end"
android:contentDescription="@string/shared_discard"
android:src="@drawable/ic_baseline_thumb_down_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/item_recipe_details"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/item_recipe_rating"
/>

With this, you add a thumbs-down icon to the list item that you can tap to discard
the recipe.

To finish your view’s layout, you’ll constrain the button to view the recipe that is
next to it.

Add this attribute to the view with the ID item_recipe_details:

app:layout_constraintStart_toEndOf="@id/item_recipe_discard"

Remove this constraint from the same view:

app:layout_constraintStart_toStartOf="parent"

This constrains the icon to view the details, so it sits next to the discard icon.

raywenderlich.com 132
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

Finally, you need to set a click listener for the new icon.

Return to the bind() method in TryItRecipesRecyclerViewAdapter.kt, and add the


following click listener:

binding.itemRecipeDiscard.setOnClickListener {
onDiscardRecipe(recipe)
}

This will discard the recipe when you tap the button. Build and run to ensure the new
option to discard a recipe works.

Screenshot of discard button.


There is one more minor issue to address, which you’ll do during a challenge at the
end of this chapter. This icon needs the same content description treatment that you
gave the view icon so that you don’t have multiple items labeled as Discard.

Considering Touch Targets


Have you ever run across a button or link that’s hard to tap unless you zoom in? This
is an example of a touch target issue. WCAG says this about touch targets:

Success Criterion 2.5.5 Target Size: The size of the target for pointer inputs
is at least 44 by 44 CSS pixels…

Level AAA

Simply said: Tappable views need to be big enough. Android guidelines recommend
at least 48dp by 48dp.

raywenderlich.com 133
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

This rule, like many others, comes with some exceptions. This chapter will cover two
from the list.

1. Equivalent: The target is available through an equivalent link or control on the


same page that is at least 44 by 44 CSS pixels.

If there’s another view on the screen that is sufficiently large and performs the same
action, it’s OK for the other to be too small.

2. Inline: The target is in a sentence or block of text.

Even though touch targets for links are generally smaller than 48dp by 48dp, you
don’t need to make them bigger to meet requirements when embedded in some text.

There are a couple of places where Taco Tuesday is noncompliant. Run the
Accessibility Scanner on both the discover view and the list of recipes to find them.

Consider making this clickable item larger.


The try it and100discard_ icons on the discover screen are too small, as well as the
view and discard icons on the list items.

Jetpack Compsose Tip: When using modifiers such as clickable and


toogleable, Compose will try to extend the tappable area to meet
accessibility requirements.

raywenderlich.com 134
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

Fixing Touch Targets


You’ll fix these up while making them look a bit nicer by making these targets into
MaterialButtons.

Open fragment_discover.xml and find the views with the IDs


discover_button_discard and discover_button_try.

Starting with the view with the ID discover_button_discard, change ImageView to


be com.google.android.material.button.MaterialButton.

Delete this attribute:

android:src="@drawable/ic_baseline_thumb_down_24"

And add these:

style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_margin="@dimen/space_normal"
android:text="No thanks"
app:icon="@drawable/ic_baseline_thumb_down_24"
app:iconPadding="@dimen/drawable_padding"

The view should now look like this:

<com.google.android.material.button.MaterialButton
android:id="@+id/discover_button_discard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?colorBackgroundFloating"
android:clickable="true"
android:focusable="true"
android:contentDescription="@string/shared_discard"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_margin="@dimen/space_normal"
android:text="No thanks"
app:icon="@drawable/ic_baseline_thumb_down_24"
app:iconPadding="@dimen/drawable_padding"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/discover_button_try"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent" />

raywenderlich.com 135
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

These changes add numerous benefits and make your app more navigable:

1. The buttons now meet requirements.

2. There’s a little extra space around the button, making the touch targets easier to
tap and more distant from their neighbors.

3. There’s now text to make the tapping action’s purpose clearer.

Add the equivalent changes to the view with the ID discover_button_try. Your
result should look like this:

<com.google.android.material.button.MaterialButton
android:id="@+id/discover_button_try"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?colorBackgroundFloating"
android:clickable="true"
android:focusable="true"
android:contentDescription="@string/shared_try_it"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_margin="@dimen/space_normal"
android:text="Save for later"
app:icon="@drawable/ic_baseline_thumb_up_24"
app:iconPadding="@dimen/drawable_padding"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/
discover_button_discard" />

Now you have all these benefits, plus some nice style improvements, on both
buttons.

Build and run to see the changes.

New buttons on the discover screen.


You’ll repeat the same for the list items’ icons.

raywenderlich.com 136
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

Open item_try_it_recipe.xml, and find the views with IDs item_recipe_discard


and item_recipe_details. Make the same changes you did above so that they look
like this:

<com.google.android.material.button.MaterialButton
android:id="@+id/item_recipe_discard"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:iconGravity="end"
android:contentDescription="@string/shared_discard"
android:textColor="?colorOnPrimary"
app:icon="@drawable/ic_baseline_thumb_down_24"
app:iconTint="?colorOnPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/item_recipe_details"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/item_recipe_rating"
/>

<com.google.android.material.button.MaterialButton
android:id="@+id/item_recipe_details"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/shared_details"
android:textColor="?colorOnPrimary"
app:icon="@drawable/ic_baseline_view_24"
app:iconTint="?colorOnPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/item_recipe_discard"
app:layout_constraintTop_toBottomOf="@id/item_recipe_rating"
/>

Now your recipe list items have buttons that meet WCAG guidelines for touch target
size! Build and run to see the changes.

New buttons on list items.


Run the Accessibility Scanner to confirm all touch target suggestions are addressed.

raywenderlich.com 137
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

Note: Another way to make views adhere to the minimum touch target size is
to set a minimum height and width on the view or increase the padding. In
some designs, where these simple fixes don’t work, you can use a
TouchDelegate.

TouchDelegate is a helper class that lets your set the touch area for a view to
be different than the view’s bounds. You create it with a Rect for the bounds
you want to be clickable, then you assign it to the view.

Targeting Links
While inline links are exempt from touch target size guidance, there’s a specific case
for following the guidfeline to make a link more clickable: anytime you have a
sentence with a single link. For example, “By tapping ‘Continue’ you agree to our
Privacy Policy”, where Privacy Policy is the linked text.

In this scenario, you can make the full-text view tappable to increase the touch
target size.

Apply this to the “Recipe from TacoFancy” text on the details screen.

Recipe from TacoFancy.

raywenderlich.com 138
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

First, remove the explicit link from the String:

1. Open strings.xml.

2. Replace the value of the String named


recipe_detail_recipe_from_tacofancy with the following:

Recipe from TacoFancy

This removes the anchor tag from the String.

Next, open RecipeDetailFragment.kt and find showRecipeDetails(). Add the


following click listener to this method:

recipeDetailCreditText.setOnClickListener {
startActivity(Intent(
Intent.ACTION_VIEW,
Uri.parse("https://github.com/sinker/tacofancy")))
}

Now you have a click listener that opens the TacoFancy URL when you tap the view.

Finally, you’ll remove the LinkMovementMethod from the view since you’re no longer
using an inline link. You can decide if you want to apply a Span to keep the link
styling.

In the same showRecipeDetails() method, remove the following line:

recipeDetailCreditText.movementMethod =
LinkMovementMethod.getInstance()

This removes the explicit movementMethod — you no longer need it.

Build and run to ensure that tapping anywhere on the text opens the link in a
browser.

raywenderlich.com 139
Android Accessibility by Tutorials Chapter 7: Operable — Navigating the Screen

Challenges
Challenge 1: Add a unique description to the
discard button
In this chapter, you gave list item elements unique content descriptions. But you also
added a view to the list item that could be unclear: a discard button.

For this challenge, you’ll add a unique content description to this button, following
the pattern you did before. A String resource has been created to give you a starting
point: try_it_description_discard_recipe.

Try to implement this yourself, then check your results against the chapter
materials’ challenge solution.

Key Points
• Operability is a crucial part of achieving accessibility.

• Accessibility tools help you identify operability issues within an app’s navigation.

• All elements of a given view must be reachable via a keyboard interface.

• Content descriptions for different list items should be unique so that the user can
differentiate between similar items.

• Focus ordering should flow in a logical pattern.

• When performing operations on list items, make sure a screen reader can keep its
focus on the correct element.

• Make link text clear and descriptive, and use TtsSpan when applicable.

• Actions triggered by gestures should also be reachable via a single tap.

• Touch targets should be at least 48dp by 48dp.

raywenderlich.com 140
8 Chapter 8: Operable —
Movement & Timing
By Victoria Gonda

Timed content can be impossible for some people to consume. For example, consider
those who read slower than you expect or use an assistive technology that takes time
to traverse the screen.

Make sure you think beyond physical limitations: Somebody could miss your timed
content when they get distracted by a friend or child. On top of that, some people
find time limits to be stressful. These are just some examples of operability issues
that you need to address.

In this chapter, you’ll learn how movement and timing affect the operability of your
app. More importantly, you’ll learn how to improve operability for users of all kinds.

The following WCAG guideline will be the focus of this chapter:

Guideline 2.2 Enough Time: Provide users enough time to read and use
content.

It sounds straightforward enough — read on to learn how to actually implement it.

raywenderlich.com 141
Android Accessibility by Tutorials Chapter 8: Operable — Movement & Timing

Considering Adjustable Timing


When building an app, WCAG wants you to provide the user with several options to
control the timing and give the user control over time limits:

Success Criterion 2.2.1 Timing Adjustable: For each time limit that is set by
the content, at least one of the following is true:

· Turn off: The user is allowed to turn off the time limit before encountering
it; or

· Adjust: The user is allowed to adjust the time limit before encountering it
over a wide range that is at least ten times the length of the default setting; or

· Extend: The user is warned before time expires and given at least 20
seconds to extend the time limit with a simple action, for example, “press the
space bar”, and the user is allowed to extend the time limit at least ten times;
or

· Real-time Exception: The time limit is a required part of a real-time event,


for example, an auction, and no alternative to the time limit is possible; or

· Essential Exception: The time limit is essential and extending it would


invalidate the activity; or

· 20 Hour Exception: The time limit is longer than 20 hours.

Level A

This criterion gives six options to consider for time limits. To summarize with two
helpful points:

1. Allowing the user to turn off or control a time limit.

2. Determining that the restriction doesn’t apply because it’s a requirement for the
function or over twenty hours.

raywenderlich.com 142
Android Accessibility by Tutorials Chapter 8: Operable — Movement & Timing

Reviewing Taco Tuesday’s Timing


Right now, if you don’t decide whether to try a recipe in the first 15 seconds, Taco
Tuesday will automatically switch to the next recipe. This behavior isn’t compliant
with Success Criterion 2.2.1.

Open Taco Tuesday. You can pull Taco Tuesday from the starter project in the
materials for this chapter, or you can use the one you’ve been working on through
this book.

Build and run so that you can experience this timed behavior.

How would you change the behavior to conform to the guidance and success
criterion?

Turn off

You can turn off the time limit in a couple of ways:

• Allow the user to choose not to have a time limit before encountering it, perhaps
presenting the user an option during the onboarding flow.

• Impose no time limit by default and provide an option to opt-in to a time limit in
the settings.

Adjust

Let the user decide what length they want this time limit to be. Right now, the
default is 15 seconds. You’d need to give an option at least ten times that length,
which would be 150 seconds.

Extend

To extend, you’d need to slightly change the behavior and give the user at least 20
seconds of warning that the recipe will change. That means the default would need
to be 20 seconds or more. You’d also need to show the user a countdown and provide
a single-tap option to extend the limit.

raywenderlich.com 143
Android Accessibility by Tutorials Chapter 8: Operable — Movement & Timing

Real-time exception

This doesn’t apply to Taco Tuesday because the app doesn’t relate to something in
the real world, such as a limited-duration sale or a due date.

If you have an app that falls into this category, you can make it compliant by
informing the user how much time they have left.

Essential exception

Similar to the real-time exception, this scenario doesn’t apply to Taco Tuesday. It’s
relevant in time-based games where changing the timing would invalidate the game.
Maybe you could gamify Taco Tuesday to make use of this guideline!

20 Hour exception

Finally, if the time limit exceeds 20 hours, you’re in the clear. How many
milliseconds are in 20 hours?

Giving Auto-Update Controls


For Taco Tuesday, you’ll fix the issues discussed above while also fixing it to comply
with a related criterion:

Success Criterion 2.2.2 Pause, Stop, Hide: For moving, blinking, scrolling, or
auto-updating information, all of the following are true:

· Moving, blinking, scrolling: For any moving, blinking or scrolling


information that (1) starts automatically, (2) lasts more than five seconds, and
(3) is presented in parallel with other content, there is a mechanism for the
user to pause, stop, or hide it unless the movement, blinking, or scrolling is
part of an activity where it is essential; and

· Auto-updating: For any auto-updating information that (1) starts


automatically and (2) is presented in parallel with other content, there is a
mechanism for the user to pause, stop, or hide it or to control the frequency of
the update unless the auto-updating is part of an activity where it is essential.

Level A

raywenderlich.com 144
Android Accessibility by Tutorials Chapter 8: Operable — Movement & Timing

Taco Tuesday auto-updates the content of the recipe cards. Per Success Criterion 2.2,
you need to provide a way for the user to “pause, stop, or hide it or to control the
frequency of the update.”

You’ll add a setting to allow the user to turn off the auto-advance feature. Then, in
Chapter 11, “Designing for Neurodiversity”, you’ll improve this feature further to
give an option for length of time.

Implementing Auto-Advance Controls


Open root_preferences.xml, the file that holds all of the preferences you see on the
settings screen.

To support multiple display options later, add this PreferenceCategory to the top
of the PreferenceScreen:

<PreferenceCategory app:title="@string/display_header">

</PreferenceCategory>

This creates an empty preference category with a header that signals it’s for display
purposes.

Next, add a switch preference to your new preference category:

<SwitchPreferenceCompat
app:defaultValue="false"
app:key="auto_advance"
app:title="@string/preference_auto_advance_title" />

This adds a new switch preference to your settings screen. When it’s off, the recipes
won’t auto-advance, and when it’s on, they will.

Notice that you set the default to false. This is because the user currently doesn’t
have an option to turn it off before they encounter the limit, which the success
criterion specifies they should. So you turn it off for now.

Now, you need to use the value of the preference. Open DiscoverViewModel.kt.

Add the following property to the DiscoverViewModel constructor:

private val sharedPreferences: SharedPreferences

This creates a reference to SharedPreferences that you can read.

raywenderlich.com 145
Android Accessibility by Tutorials Chapter 8: Operable — Movement & Timing

If the property is underlined in red it wasn’t automatically imported, import it by


setting the cursor on SharedPreferences text marked red and pressing Alt-Enter.

The reference to SharedPreferences will be passed in — the dependency injection


is preconfigured for you.

Next, find fetchRandomTaco() in DiscoverViewModel. Look for the statement that


looks like this:

fetchTacoJob = viewModelScope.launch(Dispatchers.IO) {
delay(15000) // 15 seconds
fetchRandomTaco()
}

This code snippet is responsible for the 15-second auto-advance feature. Wrap it in
the following if statement:

if (sharedPreferences.getBoolean("auto_advance", false)) {
// ...
}

This checks SharedPreferences for the settings and only advances the recipe if the
user has turned on the feature.

Build and run.

Open app’s settings and toggle your new auto-advance setting to make sure it works
as expected. When it’s off, the recipes shouldn’t advance, and when on, they should
advance every 15 seconds.

Auto advance recipes switch in settings.

raywenderlich.com 146
Android Accessibility by Tutorials Chapter 8: Operable — Movement & Timing

Managing Interruptions
Interruptions are another example of events where timing matters. You may need to
make adjustments to ensure your app is accessible. Consider the following criterion:

Success Criterion 2.2.4 Interruptions: Interruptions can be postponed or


suppressed by the user, except interruptions involving an emergency.

Level AAA

Open Taco Tuesday to see how this works.

Every two minutes, you should see a pop-up dialog with a message. For another
example of this, think about the last time an app asked you for a rating or urged you
to take another action.

Dialog pop-up.
This behavior is disruptive. Consider how it works in Taco Tuesday:You’re trying to
decide whether to try a recipe. But you’re on a time limit to decide before the next
dialog shows up. Depending on the tools you use to interact with the app, you may
need to start over after the dialog shows up.

Success Criterion 2.2.4 advises you to allow the user to delay an interruption.

To make Taco Tuesday compliant, you’ll remove the interruption entirely, but you’ll
still share the information with the user. Instead of a disruptive dialog, you’ll use a
banner across the top of the screen.

raywenderlich.com 147
Android Accessibility by Tutorials Chapter 8: Operable — Movement & Timing

Replacing the Dialog


You’ll start by adding a view to hold the banner.

Open activity_main.xml. In the parent ConstraintLayout, add the following


TextView:

<TextView
android:id="@+id/main_banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:padding="@dimen/space_normal"
android:textColor="?colorOnPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" />

This adds a full-width TextView with a background color to act as a banner. It’s in
the MainActivity, so it will display above every fragment placed in this activity.

Add the following attribute to the fragment with ID nav_host_fragment in the


same file:

app:layout_constraintTop_toBottomOf="@id/main_banner"

This line ensures the fragments align correctly below the banner.

Remove this attribute from the fragment with ID nav_host_fragment:

app:layout_constraintTop_toTopOf="parent"

This constrains the fragment view below the banner.

Next, you’ll populate this banner.

Open MainActivity.kt and find onCreate(). In this method, find the coroutine
block that starts with lifecycleScope.launch.

Right under the randomMessage declaration, add the following:

binding.mainBanner.text = randomMessage

This sets the random message to the banner view.

raywenderlich.com 148
Android Accessibility by Tutorials Chapter 8: Operable — Movement & Timing

Now, you can delete the dialog. In that same place, delete the following code:

if (dialog?.isShowing != true && !isFinishing) {


dialog = AlertDialog.Builder(this@MainActivity)
.setMessage(randomMessage)
.setPositiveButton("Close", null)
.show()
}

This removes the code that displays the dialog.

Finally, remove this property from the top of MainActivity:

private var dialog: AlertDialog? = null

Here, you remove a property that’s no longer used; it referenced the dialog that no
longer exists.

Build and run. Check out your new banner.

Message banner.

Fixing the Tests


The tests will still look for the dialog you just deleted, so you need to modify the
tests’ logic.

Run the tests in DiscoverFragmentTest to confirm failure. For reference, the tests
are looking for a view that contains the text “Close”!

Open DiscoverFragmentTest.kt. In launchFragment(), delete the following:

Espresso.onView(ViewMatchers.withText("Close"))
.perform(ViewActions.click())

This change removes the dialog you deleted from the test criteria.

Rerun the tests to confirm that you don’t see this error.

raywenderlich.com 149
Android Accessibility by Tutorials Chapter 8: Operable — Movement & Timing

Identifying Time Limits in Your App


Some time limits are more overt than others. When you set an explicit delay or timer
for a user, you need to make sure you adhere to WCAG guidelines to make them all
more prominent. But what about less-than-explicit cases? Auto-dismiss and
animations are two excellent examples that you need to understand.

Auto-dismiss

Some Android components inherently dismiss after a set amount of time. Take the
Snackbar for an example: This little view pops up on the bottom of the screen, has
an auto-dismiss option and sometimes requests the user to perform some action.

Snackbars have many baked-in accessibility features. For example, they integrate
with TalkBack. But you shouldn’t forget about them — even people who don’t use
assistive technologies and have no disabilities could easily miss a Snackbar.

When adding a Snackbar, consider if it’s acceptable for the user to miss it or fail to
react in time.

If the user must see the message or action, you need to either provide the
information another way or make the Snackbar display until the user performs a
specific action.

Animations

Animations are powerful tools to communicate ideas. Usually, when an animation


completes, you move on to the next idea and related animation. But what if a user
misses the information that goes with one of those animations?

Always make sure the user can see that information. The obvious way to do this is to
create user controls to advance, pause, set the timing or go back.

Whatever you decide, make sure you follow WCAG guidelines so that your hard work
is enjoyable for all users.

Mitigating the Risk of Adverse Reactions


For some users, on-screen movement causes adverse reactions. Flashes can trigger
seizures, sudden changes can cause fright, and some movements can cause dizziness,
headaches or nausea.

raywenderlich.com 150
Android Accessibility by Tutorials Chapter 8: Operable — Movement & Timing

WCAG has a guideline for this:

Guideline 2.3 Seizures and Physical Reactions: Do not design content in a


way that is known to cause seizures or physical reactions.

Since physical reactions can be life-threatening, Taco Tuesday doesn’t include any
examples to fix. Instead of an exercise, you’ll read how to reduce the risk of your
project causing negative reactions.

Eliminating Flashes
If your app includes things that flash or images that rapidly change, you may need to
comply with this criterion:

Success Criterion 2.3.1 Three Flashes or Below Threshold: [Screens] do


not contain anything that flashes more than three times in any one second
period, or the flash is below the general flash and red flash thresholds.

Level A

The definition for “general flash and red flash thresholds” includes specific numbers
to help you determine your app’s conformance, including guidelines related to speed,
area on the screen, luminance and color.

You can find that definition on the WCAG website (https://www.w3.org/WAI/


WCAG21/Understanding/three-flashes-or-below-threshold.html#dfn-general-flash-
and-red-flash-thresholds).

Understanding Compassionate Motion


With this criterion, you’ll find that with animations, less really is more.

Success Criterion 2.3.3 Animation from Interactions: Motion animation


triggered by interaction can be disabled, unless the animation is essential to
the functionality or the information being conveyed.

Level AAA

raywenderlich.com 151
Android Accessibility by Tutorials Chapter 8: Operable — Movement & Timing

Here are two best practices you can implement right away — people with conditions
such as vestibular disorder, aka “inner ear” disorder, will appreciate it:

1. Avoid unnecessary motion.

2. Allow the user to turn off any non-essential animation.

Test out number two right now: Go to Accessibility Settings on your device and
look for an option to turn off animations.

Note: This might be under Text and display in your accessibility settings.

Remove animations accessibility settings.


Now examine how the current settings affect animations in various apps. Does it
turn them off? If you’re in your own app, it may or may not work for any home-
grown animations. Many Android libraries already take care of this for you — some
don’t.

The third best practice requires you to do more learning. You need to understand
what kinds of movements are likely to trigger adverse reactions. A known trouble-
maker is parallax scrolling. With this kind of scrolling, different items move at
different speeds or directions. You can easily understand how that might cause a user
difficulty.

raywenderlich.com 152
Android Accessibility by Tutorials Chapter 8: Operable — Movement & Timing

Key Points
• Provide users with more than enough time to complete a task.

• Give users control over any time limits your app imposes.

• Make sure a user can pause or return to any auto-updated content.

• Avoid interrupting your user with well-meaning dialogs, pop-ups, messages or


animations.

• Avoid, or carefully design, features that include an auto-dismiss timer or


animation-controlled timing.

• Make sure the user can easily control all speeds and extend any timers.

• Avoid adding anything that flashes to an app.

• Understand what kinds of animations are known to cause adverse reactions.

• Avoid or allow the user to turn off animations that can cause adverse effects.

Where to Go From Here?


This was the final chapter about making your app operable. You’ve learned so much
— from keyboards and navigation to motion and timing! Pat yourself on the back.

Before moving onto Chapter 9, “Understandable”, take some time to investigate any
of the Operable topics (https://www.w3.org/TR/WCAG21/#operable) covered so far
that you’re interested in or might apply to your app.

raywenderlich.com 153
9 Chapter 9:
Understandable
By Victoria Gonda

Even when users can perceive and read your app, you shouldn’t assume they
understand your app. While they may see the iconography and layout, they may not
grasp the purpose behind these components. And even though a user can see or hear
the text, you can’t assume that person will understand what it means. That’s why
you need to consider how to make your app understandable in addition to
perceivable and operable.

WCAG’s guidance for this third pillar is:

3. Understandable: Information and the operation of user interface must be


understandable.

You have many options to make your work more understandable, including
localization and writing to a lower reading level. Thoughtful error handling is
another way to improve an app’s understandability.

You’ll work through some of these options using Taco Tuesday. Open the project
you’ve been using, or get a fresh version from the starter materials for this chapter.

raywenderlich.com 154
Android Accessibility by Tutorials Chapter 9: Understandable

Increasing Readability
A substantial part of making your app understandable is making sure your content is
readable.

Guideline 3.1 Readable: Make text content readable and understandable.

Here are some of the ways you can make an app more readable:

• Internationalization (or i18n) and localization (or l10n).

• Avoiding long blocks of text.

• Pairing icons with text.

• Using different fonts or allowing user-selected fonts.

• Avoiding unusual words.

• Explaining abbreviations.

This section will look at each of these examples in more detail.

Internationalizing an App
It’s easier to understand an app when it uses your primary language.
Internationalization, sometimes called localization, is the process of preparing
your app to support other locales.

Translation is a significant part of the process, but there’s more to it.


Internationalization also comprises:

• Supporting right-to-left (RTL) layouts.

• Watching for local symbols such as currency.

• Adapting for the user’s date and time formats.

Localizing your app will make it more understandable to audiences around the
world. Depending on your market, it could be a lucrative pursuit to internationalize
your app.

raywenderlich.com 155
Android Accessibility by Tutorials Chapter 9: Understandable

Using String Resources for Translations


Android allows you to put all your strings in XML resource files. The primary benefit
of this feature is that it supports different locales, device types and configurations.
Before you send off an app for internationalization, you need to:

1. Put all your strings in resource files.

2. Provide translated alternatives for these strings.

Taco Tuesday mostly uses string resources, but the bottom navigation bar doesn’t.
That’s going to result in some of your text displaying in English, even if you choose
another language. You need to fix this before uploading any translations.

Open bottom_navigation_menu.xml; this is the resource where you define the text
for the bottom navigation.

For each item, there is a title. Replace the titles as directed:

• Discover with @string/bottom_bar_discover

• Favorites with @string/bottom_bar_try_it

• Settings with @string/bottom_bar_settings

These changes inform the bottom navigation to use the string resources so they can
be translated more easily. Additionally, this change improves Taco Tuesday’s
consistency — which you’ll explore more later.

In fragment_discover.xml, on the view with ID discovery_card_detail_button,


replace:

android:text="View"

With:

android:text="@string/shared_details"

Now, the View button on the discover card also uses string resources.

A few other places don’t use string resources, and you’ll fix these later when you
learn about consistency.

You’re ready to add the translations.

raywenderlich.com 156
Android Accessibility by Tutorials Chapter 9: Understandable

Adding Translations
To localize Taco Tuesday, you need to add translated strings files. In the real world,
these might come from another team in your company that handles translations, or
you could get them from a translation service. Fortunately, Taco Tuesday
translations are provided for you.

Look for the translated strings.xml files in the materials for this chapter, in the
assets folder.

Strings assets in project materials.


Move these values-b+ folders under res in Taco Tuesday.

Strings files in Android Studio.


If you set the device language to Spanish, Portuguese, Croatian or Dutch, the app will
use that language.

Note: Sometimes these language options are displayed by the system with
their translated name - so you can try Español, Português, Hrvatski, and
Nederlands.

Settings screen with various translations.

raywenderlich.com 157
Android Accessibility by Tutorials Chapter 9: Understandable

The recipes themselves are not translated. You might recall that WCAG has different
guidelines for user-generated content. TL;DR, in most cases, you don’t need to
translate it.

Note: Some languages have lines that are much longer than the others. Now
you have another reason to support flexibility in the sizing of TextViews, in
addition to scaleability — you covered these in Chapter 4, “Perceivable —
Layout & Labeling”.

Supporting Right-to-Left Layouts


To support RTL layouts, you need to:

1. Use start/end attributes in your layouts instead of left/right.

2. Enable RTL in your AndroidManifest.

The layouts in Taco Tuesday are already using start/end attributes. However, you do
need to enable RTL in your AndroidManifest.

Add the following attribute to the application tag in AndroidManifest.xml:

android:supportsRtl="true"

You can try out your app using RTL without changing your language or locale. Go to
your device’s developer options in settings and look for Force RTL layout direction.

Developer options to force RTL.

raywenderlich.com 158
Android Accessibility by Tutorials Chapter 9: Understandable

Notice that most of the controls have flipped to the other side of the screen.

Taco Tuesday forced RTL.

Note: You probably noticed that some text elements are still left-justified.
This is because the system is detecting the English text as a left-to-right (LTR)
language. If these strings were written in an RTL language, they would right-
justify.

Using Local Formats


People format values differently depending on where they live or what language they
speak.

Dates, for example, are formatted differently around the world. In the United States,
10/12/2020 means October 12th, 2020 but it looks like December 10th, 2020 to people
from other countries.

Most date libraries support formatting a date based on the user’s locale. For this app,
you can do this using Android’s DateFormat.

For example, add a timestamp to the error that shows when you tap “Compliment
the Chef” on the recipe detail screen.

First, add a slot for the date in the string resource. Open strings.xml and modify
shared_generic_error_message to tack on \n%s to the end of the message. Make
sure you do this for all languages.

raywenderlich.com 159
Android Accessibility by Tutorials Chapter 9: Understandable

Next, open RecipeDetailFragment.kt and import


android.text.format.DateFormat while adding the following code to the
recipeDetailComplimentTheChef click listener at the bottom of the
showRecipeDetails method.

val currentDate = Date()


val dateFormat = DateFormat.getMediumDateFormat(context)
val formattedDate = dateFormat.format(currentDate)
binding.recipeDetailErrorView.text = requireContext().getString(
R.string.shared_generic_error_message, formattedDate
)

Build and run the app. View the details for a recipe and tap “Compliment the Chef”
at the bottom of the view. You should see the message similar to the following, but
with today’s date:

Taco-bout a mess! We ran into an error when trying to do that


Aug 7, 2022

You can also use other methods from DateFormat, such as getLongDateFormat(), to
get something that looks like Monday, January 3, 2000.

Similarly, you can use Currency.getInstance() to get the correct currency for a
user’s locale.

Avoiding Long Blocks of Text


Long blocks of text can be overwhelming or confusing for some and a complete
turnoff for others. Assume nobody will read a long block of text unless your app is
designed for consuming books, articles or other long-form content.

Choose to show shorter bits of text whenever you can. You can break blocks into
smaller slices, or you can hide most of the text and allow the user to expand the text
to read more. You can also edit it down to its pure essence.

In Taco Tuesday, there’s too much text on the swipeable cards on the main screen. If
you’re flipping through while starving for tacos, you’re probably only really seeing
the title.

raywenderlich.com 160
Android Accessibility by Tutorials Chapter 9: Understandable

You don’t really need much more.

Recipe card with a lot of text.


To make this screen more pleasant, you’ll make the image bigger and show less text.

Start by updating the image size. Open fragment_discover.xml and find the view
with the ID discover_recipe_image. Change the value of the
app:layout_constraintDimensionRatio to 2:1:

app:layout_constraintDimensionRatio="2:1"

You’ve changed the ratio of the image, and now it takes up more of the card.

Next, add some margin to the text on this card. Add the following to the view with ID
discovery_card_recipe_description:

android:layout_margin="@dimen/space_normal"

This adds some nice space between the text and the edges of the card.

Then, bump the text size of the discovery_card_recipe_description view up to


12sp:

android:textSize="12sp"

raywenderlich.com 161
Android Accessibility by Tutorials Chapter 9: Understandable

Now, you have a more readable font size — 9sp is too small to be readable! This
change also fixes an accessibility lint warning.

Build and run. It already looks so much nicer!

Recipe card with less text.

Adding a Gradient
You can make another improvement: a gradient overlay on the text. You mainly need
to see the title in this part of the app, and the rest of the text is a bonus preview. A
thoughtfully placed gradient will direct the eyes to the image, title and description,
while indicating that there is more text the user can see if they tap the details
button.

Add this view below the discovery_card_recipe_description view:

<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/recipe_preview_gradient"
app:layout_constraintBottom_toBottomOf="@id/
discovery_card_recipe_description"
app:layout_constraintEnd_toEndOf="@id/
discovery_card_recipe_description"
app:layout_constraintStart_toStartOf="@id/

raywenderlich.com 162
Android Accessibility by Tutorials Chapter 9: Understandable

discovery_card_recipe_description"
app:layout_constraintTop_toTopOf="@id/
discovery_card_recipe_description" />

Build and run again. You now have a nice gradient! It looks so much more polished.

Recipe card with gradient.

Pairing Icons With Text


Icons’ meanings are not always precise. An icon could be new to a user, culturally
specific or ambiguous. Be careful when choosing icons. They might not be as
universal or explicit as you’d think.

Contextualizing icons can be tricky. You can show text alongside the icon, provide a
legend someplace, include context during onboarding or add a tooltip.

In Taco Tuesday, you’ll pair text with icons. The recipe list has icons that could be
interpreted in many ways.

Ambiguous icons.

raywenderlich.com 163
Android Accessibility by Tutorials Chapter 9: Understandable

To add some text for these icons, head over to item_try_it_recipe.xml.

Add the following to the view with the ID item_recipe_discard:

android:text="@string/shared_discard"

This adds text to the discard button.

Similarly, add this to the view with ID item_recipe_details:

android:text="@string/shared_details"

Now the view details button also has some text.

Optionally, remove this attribute from item_recipe_discard for some symmetry:

app:iconGravity="end"

Now, both of the buttons have icons on the same side. That’s it! Build and run to see
your changes.

Icons with text.


Now it’s more clear what those buttons do.

Using Different Fonts


This book has already covered most of what you need to know about fonts. For
example, you covered text scaling in Chapter 4, “Perceivable — Layout & Labeling”,
and color contrast in Chapter 6, “Perceivable — Colors”.

Two final notes about this topic:

1. Make sure you pick a legible font.

2. If you support system fonts, expect the user to change the device’s font either for
preference or to improve readability. Your app should handle this change well if
you’re correctly handling scaling text.

raywenderlich.com 164
Android Accessibility by Tutorials Chapter 9: Understandable

Avoiding Unusual Words


When creating copy for an app, be careful with lesser-known words.

Success Criterion 3.1.3 Unusual Words: A mechanism is available for


identifying specific definitions of words or phrases used in an unusual or
restricted way, including idioms and jargon.

Level AAA

One way to comply with this criterion is to avoid words that might be hard to
understand, such as advanced words, idioms and jargon.

Idioms are phrases where the meaning of the phrase doesn’t necessarily have
anything to do with the meanings of each word on its own. For instance, using “I’m
over the moon” as an expression to mean “I’m very happy”. Unless you’re quite lucky,
you’re probably not literally going to the moon!

Jargon is a set of words used by a profession or group that’s difficult to understand.


For instance, if you talked to another Android developer about a Manifest, they’d
know you meant the application manifest. If you talked to another kind of developer,
it might mean something quite different to them.

These words can be difficult for the user to understand or relevant to one culture but
not to another. When you can’t avoid these words, you need to define them so the
user gets the full meaning.

In Taco Tuesday, there are a lot of English-language puns that could be


misunderstood. Open up strings.xml and look at the array pop_up_options. These
are the intermittent messages that display in the app.

Intermittent message.
Many of these are fun, cringe-worthy lines. It’s sad to think that some people might
miss the meaning. They might not understand the wordplay, or it might not translate
to their native language.

What can you do in this case? You could eliminate the puns in your app, but the puns
are part of the app’s personality.

raywenderlich.com 165
Android Accessibility by Tutorials Chapter 9: Understandable

There’s no need to delete the puns; you can provide another way for the user to get
meaning. You can allow them to turn “off” the puns, or you can give them help text.

You’ll add some text alternatives to the app. When you’re done, the user can tap the
banner to read an explanation or a plainly worded version of the message.

Start by adding this string array to the English strings.xml:

<string-array name="pop_up_alternates">
<item>Are you enjoying the app? Rate it now in the Play Store!
</item>
<item>Victoria just tried a new recipe. What recipe are you
trying this week?</item>
<item>Jenn rated her favorite recipe 1 minute ago. Why don\'t
you help others by rating yours?</item>
<item>Ellen made tacos on Tuesday 5 weeks in a row. Beat her
streak!</item>
<item>Gabriella created her own taco recipe. Congratulate her!
</item>
<item>How are you liking this app? Let\'s talk about it. Answer
this five minute survey!</item>
<item>Let us help you find your next Taco Tuesday recipe! Swipe
right on your next find.</item>
<item>Did you find a recipe you dislike? Not your type of taco?
Leave a rating on the details screen.</item>
<item>Sorry to be all up in your grill. Do you mind taking a
second to rate the app?</item>
<item>Spectacular! You saved your first recipe. Ready to get
cooking?</item>
<item>Having issues with the app? We can talk over the phone.
Contact support now.</item>
<item>Shop for tortillas and other ingredients now so you\'re
not caught without them</item>
<item>Are you hungry? Try one of our delicious taco recipes!</
item>
<item>Have some feedback? You can tell us. We won\'t tell
anyone.</item>
<item>Try tacos on a day other than Tuesday. Tacos every day!</
item>
<item>Let\'s not waste time. You\'re our favorite customer!</
item>
<item>Take a chance on that recipe you\'re not sure about. You
might end up loving it!</item>
<item>Do you have the best taco pun? Share it with us on our
forum!</item>
<item>Taco Throw Back Thursday time! Share the best taco recipe
you\'ve ever made?</item>
<item>Ready for Taco Tuesday? How about you use one of our
tried and true recipes.</item>
</string-array>

raywenderlich.com 166
Android Accessibility by Tutorials Chapter 9: Understandable

These are the messages the user will see when they tap the banner. All of the puns
are removed.

Next, open MainActivity.kt. The bottom of onCreate() handles the logic for this
banner.

Move the logic in lifecycleScope.launch to pick a random index to a reusable


variable:

val randomIndex = Random.nextInt(options.size - 1)


val randomMessage = options[randomIndex]

Now you can reuse this index to get the alternate text.

Right below the line binding.mainBanner.text = randomMessage, add the


following code:

// 1
binding.mainBanner.setOnClickListener {
// 2
AlertDialog.Builder(this@MainActivity)
.setMessage(resources
.getStringArray(R.array.pop_up_alternates)[randomIndex])
.setPositiveButton(R.string.shared_dismiss, null)
.show()
}

This does two things:

1. Sets a click listener on the banner.

2. Displays a dialog using the alternate message for that index.

Build and run. Tap on the banner to see the dialog with alternate text.

Dialog with alternate text.

raywenderlich.com 167
Android Accessibility by Tutorials Chapter 9: Understandable

Explaining Abbreviations
Similar to difficult words or phrases, abbreviations can be a source of confusion.

Success Criterion 3.1.4 Abbreviations: A mechanism for identifying the


expanded form or meaning of abbreviations is available.

Level AAA

Have you ever run across an abbreviation that you had to look up? Maybe you felt
out of touch with the hip and the young, or perhaps you felt a little foolish for having
to ask. You don’t want your users to feel that way!

The first time you use an abbreviation, you should spell the whole thing out and put
the acronym in parentheses after it. For example, consider how RTL was presented
for the first time in this chapter:

Supporting right-to-left (RTL) layouts

If you’re unable to explain inline, you can take a similar approach as with the lesser-
known words and give another way to uncover the meaning.

Creating Predictability
The other part of making your app understandable is making it predictable.

Guideline 3.2 Predictable: Make web pages appear and operate in predictable
ways.

When you use consistent patterns, your app becomes more comfortable to use. Users
shouldn’t need to guess what will happen when they perform an action.

You can make your app more predictable by:

• Not changing context unexpectedly.

• Using consistent language.

• Assisting users with preventing and handling errors.

raywenderlich.com 168
Android Accessibility by Tutorials Chapter 9: Understandable

Changing Context
It can be confusing when the context changes, but the user doesn’t expect it to. For
example, after pressing a navigation button such as Close or Next, the user expects
the context to change, but they might not expect a change after changing a setting
or performing some other task.

Success Criterion 3.2.2 On Input: Changing the setting of any user interface
component does not automatically cause a change of context unless the user
has been advised of the behavior before using the component.

Level A

Right now, when you check Made it on a recipe, the recipe closes. Open the app and
try this out. It’s quite unexpected!

Made it check box.


Two options to improve it are:

1. Let the user know they are about to change contexts.

2. Don’t change contexts.

You’ll implement the second option because it doesn’t make sense to close the view
in this case—it feels like a bug to the user.

Open RecipeDetailFragment.kt. In showEditableFields(), delete this code:

recipeDetailMadeIt.setOnCheckedChangeListener { _, _ ->
activity?.onBackPressed()
}

This removes the OnCheckedChangeListener so that the screen doesn’t close when
the user takes this action. Build and run. Find a recipe and check the Made recipe
box. Be happy the view doesn’t close!

raywenderlich.com 169
Android Accessibility by Tutorials Chapter 9: Understandable

Navigating Consistently
Navigation patterns should be consistent throughout the app. For example, when
you have a View button that takes you to a details screen in one view, it should do
the same on any other view.

Success Criterion 3.2.3 Consistent Navigation: Navigational mechanisms


that are repeated on multiple Web pages within a set of Web pages occur in the
same relative order each time they are repeated, unless a change is initiated by
the user.

Level AA

Taco Tuesday’s navigation is already pretty consistent. Settings always takes you to
Settings. Discover leads to the same screen.

Fortunately for you, there is one thing to improve: button labels are inconsistent.

Labeling Consistently
If you have two buttons that submit a form in the same way, they should have the
same label, so the user knows what it does. This best practice applies to other kinds
of labels too.

Success Criterion 3.2.4 Consistent Identification: Components that have


the same functionality within a set of Web pages are identified consistently.

Level AA

You’ll address the specific issue where sometimes you use the Try it and Save for
later buttons for the same action. You have a similar problem with Discard and No
thanks. You’ll correct this by changing the labels.

Start by opening fragment_discover.xml. On the button with the ID


discover_button_discard, find this line:

android:text="No thanks"

raywenderlich.com 170
Android Accessibility by Tutorials Chapter 9: Understandable

And replace it with:

android:text="@string/shared_discard"

Similarly, on the button with ID discover_button_try, find this:

android:text="Save for later"

And replace it with:

android:text="@string/shared_try_it"

Now, these buttons use the same language as they do in the rest of the app. And if
you change the string resource, you’ll change all the button labels at once.

Build and run to see this change.

Updated button text.

Helping With Errors


Misunderstandings happen when the user doesn’t understand what’s expected of
them, and when there are errors that don’t make sense. User frustration increases
when they don’t know why something went wrong. The more frustrated they are, the
less likely they’ll keep using your app, which is why this WCAG guideline exists:

Guideline 3.3 Input Assistance: Help users avoid and correct mistakes.

You’ll explore two different ways to clarify errors in this section:

1. Announce errors and solutions when they occur.

2. Make error messages descriptive and actionable.

3. Provide descriptions for inputs.

raywenderlich.com 171
Android Accessibility by Tutorials Chapter 9: Understandable

Announcing Detailed Errors


When there’s an error, you want to describe it, clarify if it’s related to a specific field
or task and explain if and how the user can resolve it.

Success Criterion 3.3.1 Error Identification: If an input error is


automatically detected, the item that is in error is identified and the error is
described to the user in text.

Level A

Taco Tuesday throws an error when you “compliment the chef” on a recipe. It’s a
hard-coded error. In your own app, this could be a network error or invalid state.

Error message.
There are already a lot of great things about this error! The message informs the user
that something went unexpectedly. It’s also contextual because it displays where the
error happened.

Now try using TalkBack on this screen. Did you hear anything about this error? No.

There are two things that you can improve:

1. Announce it when it displays. As is, someone using a screen reader might not
know a new error exists.

2. Be more descriptive: specify what went wrong and the next steps.

One way to solve this would be to use a Toast or Snackbar to display the error. Both
components automatically work with TalkBack, which is helpful. However, these
options take the error out of context, which isn’t as helpful.

Live regions, on the other hand, keep the error message in line with the context of
the action AND make sure the screen reader announces when it displays.

raywenderlich.com 172
Android Accessibility by Tutorials Chapter 9: Understandable

Open RecipeDetailFragment.kt. In showRecipeDetails(), add this code right


before the click listener for recipeDetailComplimentTheChef:

recipeDetailErrorView.accessibilityLiveRegion =
ViewCompat.ACCESSIBILITY_LIVE_REGION_POLITE

You use accessibilityLiveRegion to determine if changes to the text or content


description of this view should be announced to the user.

Note: In general, you’ll use ACCESSIBILITY_LIVE_REGION_POLITE.

To disable, use ACCESSIBILITY_LIVE_REGION_NONE.

For cases where something is urgent enough to interrupt other


announcements, use ACCESSIBILITY_LIVE_REGION_ASSERTIVE. Use this
option sparingly.

Now, when the view displays, it will be announced. Build and run. Test out this
button again and see that it reads the error when it shows up.

Announced error message.

Writing Clear Error Messages


You should write error messages for the user. They should help the user know:

1. What went wrong.

2. How they can fix it.

You should explain what failed in the error message when you know the issue. In the
message, you can specify the offending action or show the message in the correct
context.

The error could be related to the user’s action, which they can resolve by repeating
the action correctly, or some issue that they can’t directly fix, like a loading error.

You should also give the user options for solving the issue. If it’s an internal server
issue, the solution could be to come back later or retry the action.

raywenderlich.com 173
Android Accessibility by Tutorials Chapter 9: Understandable

If it’s a validation error, tell them which requirement they missed in the most
straightforward language possible.

Your exercise for this section is to make the “compliment the chef” error message
actionable. You’ll ask the user to try again in a few minutes.

In strings.xml, add this to the end of the shared_generic_error_message string,


and before \n%s:

Please try again in a few minutes.

You don’t need to change the translations for this exercise, but you would for a
production application.

Build and run so that you can see an actionable instruction when the error displays.

Announced error message with instruction.

Providing Input Descriptions


When your app has a form or single input, you should clarify what to include in this
field so the user can avoid causing errors.

Success Criterion 3.3.2 Labels or Instructions: Labels or instructions are


provided when content requires user input.

Level A

It’s frustrating when you’re confused about what to enter. It’s more frustrating when
you get an ambiguous error and don’t understand why it happened.

You can use a description, hint, tooltip or something else. If a date must be in the
future when filling out a date, let the user know ahead of time and give them a
descriptive error when the input is invalid.

Imagine if the “Notes” field on a saved recipe required at least five characters to
save. You’d need to inform the user of that requirement up front. That way, users
don’t try to save notes that are too short and then curse your app when it fails to
save them.

raywenderlich.com 174
Android Accessibility by Tutorials Chapter 9: Understandable

Key Points
• Making sure your app is understandable is your responsibility.

• Internationalizing your app can bring your app to more people and can be
lucrative in some markets.

• Avoiding long blocks of text improves the user’s comprehension.

• Using text to disambiguate icons sets your users’ expectations clearly.

• Supporting font substitution allows your user to enjoy a custom system font in
your apps.

• Making errors avoidable and understandable reduces frustration with your


product.

raywenderlich.com 175
10 Chapter 10: Robust
By Victoria Gonda

People use their devices in many different ways, so you need to make sure your app
is compatible with accessibility services.

While much of the work happens automatically or is trivial to implement, you need
to put in effort for custom views. That’s the main focus of this chapter.

You’ve explored perceivable, operable and understandable. That means you’ve


reached the final pillar of the WCAG guidelines: Robust.

Robust: Content must be robust enough that it can be interpreted by a wide


variety of user agents, including assistive technologies.

A robust app is one that people can access in various ways, including with different
assistive technologies, such as screen readers.

Android does a lot of the heavy lifting by providing components with built-in
support. And it provides an interface for you to leverage. In this chapter, you’ll learn
how to use these built-in tools to improve your apps by providing more information
about views.

raywenderlich.com 176
Android Accessibility by Tutorials Chapter 10: Robust

Success Criterion 4.1.2 Name, Role, Value: For all user interface
components (including but not limited to: form elements, links and
components generated by scripts), the name and role can be programmatically
determined; states, properties, and values that can be set by the user can be
programmatically set; and notification of changes to these items is available
to user agents, including assistive technologies.

Level A

This criterion may sound daunting. And you’re not wrong. However, this chapter will
give you the insights and practice you need.

You can either work on the starter project for this chapter or continue with the
project you used earlier in the book.

Relying on System Views


The simplest way to satisfy the success criterion is by using the views that Android
provides. They typically include everything — or almost everything — you need to
inform accessibility services about a view’s role and content.

In other words, if you can use a system view instead of creating a custom view, do
that! You can customize it; for example, if you need a custom button, you extend the
Button rather than starting from scratch with a View.

In Taco Tuesday, you can take advantage of a system view to improve the recipe
details screen. There’s a Made it checkbox that is currently two different views: the
label and the check box.

Made recipe checkbox.

raywenderlich.com 177
Android Accessibility by Tutorials Chapter 10: Robust

Turn on TalkBack, run the app and observe how this view behaves with the screen
reader.

You must highlight them separately. There’s no indication that the checkbox belongs
to the “Made recipe” label.

Made recipe TalkBack reading.


You can improve this by including the text of the label as part of the checkbox.

Open fragment_recipe_detail.xml. Delete the label:

<TextView
android:id="@+id/recipe_detail_made_it_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/recipe_detail_made_recipe" />

You’re deleting the old view because you’ll combine these views,

You also need to delete references to this label in the Kotlin code:

1. Open RecipeDetailFragment.kt.

2. Delete the recipeDetailMadeItLabel.visibility = View.VISIBLE line in


showEditableFields().

3. Delete the recipeDetailMadeItLabel.visibility = View.GONE line in


hideEditableFields().

Then, in fragment_recipe_detail.xml, add the text of the label to the CheckBox with
ID recipe_detail_made_it:

android:text="@string/recipe_detail_made_recipe"

Now, the CheckBox owns the label and can inform the accessibility services about the
associated label.

raywenderlich.com 178
Android Accessibility by Tutorials Chapter 10: Robust

Build and run. Use TalkBack again and notice that the checkbox is correctly labeled.

Made recipe checkbox with updated TalkBack.


To make stylistic changes to the CheckBox or any other view, modify or extend the
CheckBox itself. Don’t create something new. Using existing views allows you to
leverage Android’s built-in support for assistive technologies.

Indicating a View’s Role


Although the system’s components will support most accessibility services without
any intervention, you may need to make adjustments to achieve the desired
experience. In many cases, you can use an accessibility delegate to make these
modifications.

In Chapter 7, “Operable — Navigating the Screen”, you added an


AccessibilityDelegateCompat to create a custom action name. To modify other
accessibility attributes of the view, you can employ the same pattern. Try it out for
yourself!

To prepare, add this item to strings.xml:

<string name="banner_role">banner</string>

You’ll use this in the next step. Don’t worry about translations for now.

raywenderlich.com 179
Android Accessibility by Tutorials Chapter 10: Robust

Experimenting With Delegates


Next, you’ll experiment with a delegate for the banner that displays across the top of
the screen.

1. Open the Project tab on the left side of Android Studio.

2. Create a new class named BannerAccessibilityDelegate in the


com.mycompany.android.tacotuesday package.

3. Open the new class and set it to extend AccessibilityDelegateCompat, like


this:

class BannerAccessibilityDelegate :
AccessibilityDelegateCompat()

As you did before, override onInitializeAccessibilityNodeInfo() in


BannerAccessibilityDelegate.kt, and add all neccessary imports:

override fun onInitializeAccessibilityNodeInfo(


host: View?,
info: AccessibilityNodeInfoCompat?
) {
// 1
super.onInitializeAccessibilityNodeInfo(host, info)
// 2
info?.roleDescription =
host?.context?.getString(R.string.banner_role)
}

You’re implementing two actions in this method:

1. Calling the super method so the superclass can handle its accessibility node info.

2. Setting the role description of the view to banner.

raywenderlich.com 180
Android Accessibility by Tutorials Chapter 10: Robust

Note: These actions are meant to be an example. Generally, you won’t need to
set the role.

You may need to set the role if a custom view’s role is incorrect. For example,
when you treat a non-button component like a button.

Use your new delegate: In MainActivity.kt, add this to the bottom of onCreate():

ViewCompat.setAccessibilityDelegate(
binding.mainBanner,
BannerAccessibilityDelegate()
)

Build and run. Use TalkBack to see how it announces your role.

TalkBack reading banner role.


The AccessibilityNodeInfoCompat has many properties. You can use them to
define if a view is clickable, checkable and more. Please take a few moments to
experiment with the other properties to see how they interact with TalkBack.

If some of this seems familiar, remember, that you learned how to use it to add
custom actions in Chapter 7, “Operable – Navigating the Screen”.

There are other methods you can override on AccessibilityDelegateCompat by


using methods such as onPopulateAccessibilityEvent() and
onInitializeAccessibilityEvent(). With these, you can define changes based on
events; for example, if the state changes from unchecked to checked.

You should review Android documentation for guidance about working on a custom
view that is actionable or has a changing state — this book does not go into that use
case.

The rest of this chapter will be a bit harder — you’ll focus on a more complicated
example.

raywenderlich.com 181
Android Accessibility by Tutorials Chapter 10: Robust

Note: Learn more about how to use an accessibility delegate at in the official
docs (https://developer.android.com/guide/topics/ui/accessibility/custom-
views#populate-events) and see what you can set on an
AccessibilityNodeInfoCompat (https://developer.android.com/reference/
androidx/core/view/accessibility/AccessibilityNodeInfoCompat).

Building Custom Views


Custom views can become incredibly complex with different touch areas, actions and
behaviors. You need to communicate this complexity to the accessibility services. To
make your task a little trickier, documentation around these use cases is a bit…
sparse.

Taco Tuesday has a custom view with multiple touch areas: CustomRatingBar, which
is the nacho and spiciness rating bars on the details screen.

Nacho and spice rating bars.


Try using TalkBack on this view. Spoiler alert: It needs improvement. You can’t select
individual items, discover the current rating or select a new rating.

Rating bar TalkBack selection.


As it stands, the accessibility service thinks this is a single view. It doesn’t know that
you can touch the different ratings or do other things.

Virtual views are treated as their own views from a perception and operation
standpoint. They are one means to inform accessibility services about different
touch areas.

raywenderlich.com 182
Android Accessibility by Tutorials Chapter 10: Robust

Using ExploreByTouchHelper
If you research how to create these virtual views, you’ll find many options. This
chapter will teach you how to use an ExploreByTouchHelper, a type of accessibility
delegate that can help you define touch areas.

Open CustomRatingBar.kt. Create an inner class for your touch helper delegate:

inner class CustomRatingBarExploreByTouchHelper(host: View) :


ExploreByTouchHelper(host) {
}

You’re using an inner class so that you can access properties and methods on the
CustomRatingBar.

This new inner class is where you’ll do much of the work to inform the accessibility
services about the state and events of the virtual views. Using only the above code,
the IDE will show a compiler error until you override the required methods.

Defining Virtual Views


The first things you’ll define are:

1. How many virtual views exist.

2. Where they’re located.

3. What properties do they have.

Virtual View Count

CustomRatingBar defines the locations of these views in the rectangles list. You’ll
use this list occasionally to get information about the virtual views.

Override getVisibleVirtualViews() to define how many views there are with:

override fun getVisibleVirtualViews(


virtualViewIds: MutableList<Int>?
) {
rectangles.forEachIndexed { index, _ ->
virtualViewIds?.add(index)
}
}

The parameter for this method is a list of virtual IDs. You add all your virtual IDs to
this list. For simplicity, this method uses the index of the views for the IDs.

raywenderlich.com 183
Android Accessibility by Tutorials Chapter 10: Robust

Virtual View Location

Next, you need to define where these views are. Add this code to
CustomRatingBarExploreByTouchHelper:

override fun getVirtualViewAt(x: Float, y: Float): Int {


// 1
val index = findRatingAtPoint(x, y)
// 2
return if (index == INVALID_VALUE) INVALID_ID else index
}

With getVirtualViewAt(), you inform the accessibility services which virtual view
was acted on at a point. By section:

1. Look up which virtual view at this location uses an existing method in


CustomRatingBar. The index is the ID.

2. Return the index of the ID if it’s valid. Otherwise, return INVALID_ID. One
reason for the latter to happen is that an area of your custom view is not a virtual
view.

Virtual View Properties

Then, you need to share the information about the view. Add this for
onPopulateNodeForVirtualView():

override fun onPopulateNodeForVirtualView(


virtualViewId: Int,
node: AccessibilityNodeInfoCompat
) {
// 1
node.text = context.getString(
R.string.custom_rating_bar_description,
label,
virtualViewId + 1
)
// 2

node.addAction(AccessibilityNodeInfoCompat.AccessibilityActionCo
mpat.ACTION_CLICK)
// 3
node.setBoundsInParent(rectangles[virtualViewId])
}

raywenderlich.com 184
Android Accessibility by Tutorials Chapter 10: Robust

Here you have the same AccessibilityNodeInfoCompat class you used when
creating delegates before. Using that node, you:

1. Set the text of the virtual view. If the view doesn’t have text, you set this to be
identical to the content description. Remember that you’re using the index as the
ID, so the first item is index 0, the second is index 1, etc. You adjust the index
value with virtualViewId + 1 to get which rating item it is to the user.

2. Add a click action to inform the services that this item is clickable.

3. Define the bounds for this view using the saved rectangle.This is also where you
can set the state for events, a checked box or some error. Now the accessibility
services know what to read when they reach this virtual view.

Note: node.setBoundsInParent(rectangles[virtualViewId]) line will


show as deprecated. Don’t worry about it. At the time of writing, there’s a bug
that causes the app to crash if you don’t include it.

Performing Actions
Finally, when someone initiates a click action, regardless of if it was with a physical
tap or through an accessibility service, you need to add logic to handle it correctly.

Override this last method in CustomRatingBarExploreByTouchHelper:

override fun onPerformActionForVirtualView(


virtualViewId: Int,
action: Int,
arguments: Bundle?
): Boolean {
when (action) {
AccessibilityNodeInfoCompat.ACTION_CLICK -> {
onSelected(virtualViewId)
return true
}
}
return false
}

This view handles click actions, and because there is already a helper method for this
action, you’re:

• Checking for a click action on the selected ID.

• Calling onSelected() when there is a click action.

raywenderlich.com 185
Android Accessibility by Tutorials Chapter 10: Robust

Linking the View and Delegate


Now you’re ready to hook up the delegate that defines your virtual views to your
custom view.

Add this property to CustomRatingBar:

private val exploreByTouchHelper =


CustomRatingBarExploreByTouchHelper(this)

You’ve just initialized a property for your touch helper delegate and can access the
delegate in all the places you need it.

At the bottom of the init block, add this line:

ViewCompat.setAccessibilityDelegate(this, exploreByTouchHelper)

Now your delegate is added to the view.

Finally, add these methods to CustomRatingBar:

override fun dispatchHoverEvent(event: MotionEvent?): Boolean {


return (event?.let {
exploreByTouchHelper.dispatchHoverEvent(it)
} ?: run { false }
|| super.dispatchHoverEvent(event))
}

override fun dispatchKeyEvent(event: KeyEvent?): Boolean {


return (event?.let {
exploreByTouchHelper.dispatchKeyEvent(it)
} ?: run { false }
|| super.dispatchKeyEvent(event))
}

override fun onFocusChanged(


gainFocus: Boolean,
direction: Int,
previouslyFocusedRect: Rect?
) {
super.onFocusChanged(gainFocus, direction,
previouslyFocusedRect)
exploreByTouchHelper.onFocusChanged(gainFocus, direction,
previouslyFocusedRect)
}

This large chunk forwards the required methods to the accessibility delegate.

raywenderlich.com 186
Android Accessibility by Tutorials Chapter 10: Robust

Phew! You made it. Build and run. Use TalkBack to navigate through and select a
rating.

TalkBack nacho rating selection.

Improving the State


When using TalkBack, you can’t discern a recipe’s current rating or know when it
changes. This diminishes the experience, so you’ll set the content description to the
current rating when a user rates a recipe.

You’ll accomplish this by adding to a custom setter on the rating variable.

Create a string resource for this description by adding this to strings.xml:

<string name="current_rating_description">Current rating is %d</


string>

Don’t worry about adding translations for this exercise.

Then, append the content description in the custom rating property setter
underneath invalidate() in CustomRatingBar.kt:

contentDescription =
context.getString(R.string.current_rating_description, value)

The content description now includes the current rating.

You can further improve the experience by making sure that TalkBack announces
when the rating has changed. You learned a trick about setting the accessibility live
region in Chapter 9, “Understandable”, which you’ll use here.

Add this line to the bottom of the init block:

accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_POLITE

When the content description changes, it will be announced.

raywenderlich.com 187
Android Accessibility by Tutorials Chapter 10: Robust

Build and run. Try to change the rating using TalkBack, and listen for it to announce
the change.

Current rating announced.


This view is now MUCH more accessible. Great work!

Seeing Service Limitations


While working through this book, you might have noticed that different devices and
Android builds support different accessibility services. The differences go deeper
than that.

You cannot rely on accessibility services behaving similarly on different devices.


Manufacturers configure these services differently, and users can modify settings
that change the services’ behaviors.

There are some compat classes to help you handle different Android versions, and in
many cases, you can rely on these. They’re helpful when you’re working with APIs
that are only supported on newer versions.

This book has not covered accessibilityTraversalAfter and


accessibilityTraversalBefore because they’re known to have inconsistent and
unreliable behavior on some devices.

Because of these constraints, you should avoid trying to make a view behave a
specific way when you’re testing. You should assume that the user is familiar with
how these services work on their device. When testing, you should focus on ensuring
you’re giving the accessibility services accurate information and creating a
consistent experience.

Android is continually evolving and improving its accessibility technology, and each
version of Android comes with a promise for new and better services. So while it is a
challenge to keep up, you can look forward to improved services with each new
release.

raywenderlich.com 188
Android Accessibility by Tutorials Chapter 10: Robust

Challenges
Challenge 1: Fix the Rating Bar
The rating bar is editable when on the details screen and not editable when in the
list view.

That’s because something is missing from your CustomRatingBar; specifically, there


is an editable flag that is not respected when using TalkBack.

Your challenge is to make some changes so that this flag is respected.

Hint: You don’t need the accessibility delegate if the view is not editable.

Compare your results with the challenge project in the resources for this chapter. If
you get stuck, that same project will show you the solution.

Key Points
• A robust app is one that integrates with accessibility services.

• System views are the most reliable way to support accessibility across devices.

• An accessibility delegate is one of the ways to communicate details to accessibility


services.

• Use ExploreByTouchHelper to create and manage virtual views when a custom


view has multiple touch targets.

• Accessibility services often behave differently on different devices.

• Android is making continuous improvements to accessibility services.

raywenderlich.com 189
11 Chapter 11: Designing for
Neurodiversity
By Victoria Gonda

Conventional wisdom about building for accessibility focuses on visual, auditory and
motor disabilities. But another important consideration is neurodiversity.

Neurodiversity, for the sake of this discussion, is the natural variance between
people’s neurological structure and function. Brains are remarkably complex, so each
human experiences and interacts with the world in wildly different ways.

When you design an app, it’s just as important to consider users with lesser-known
syndromes, such as Williams Syndrome (a developmental disorder that can interfere
with visual and spatial reasoning), as it is to consider those who live with anxiety.
Being inclusive of these users creates a better experience, which increases their
happiness and loyalty to your product. Inclusive design also gives all of your users a
better experience.

This chapter can’t cover every experience out there — each person is unique.
However, it will give you tips to make your app more usable and enjoyable for all,
including those who live with autism, dyslexia, anxiety and ADHD.

Some of the things you’ll learn to do in this chapter include:

• Reduce time stress

• Communicate with clarity

• Provide help

• Be consistent

raywenderlich.com 190
Android Accessibility by Tutorials Chapter 11: Designing for Neurodiversity

• Watch phrasing

• Give alternatives

• Add configurability

Many of the solutions in this chapter will positively affect your Taco Tuesday
experience, even if you don’t identify as neurodiverse.

You’ll continue improving Taco Tuesday, so open the project you’ve been working on
or the starter project for this chapter. With that done, move on to the first topic:
Reducing time stress.

Reducing Time Stress


Imagine you’re filling out a form on your phone. Now, quick! Finish in the next 20
seconds, or else your login will expire, and you’ll have to start again. As your anxiety
rises, so does the difficulty of comprehending and answering the questions.
Ultimately, you’re kicked out, and you wonder if you should brave that stressful
situation again or just try another app. You’ll probably find another app.

Arbitrary or unavoidable time limits make apps unusable for some people with motor
or vision disabilities. They can also induce anxiety responses. Some people need
more time to read than you might think, and time limits interfere with their ability
to comprehend and act.

WCAG wants you to avoid imposing arbitrary time limits. When you do need time
limits, allow the user to extend the time whenever possible. In cases where time is
literally critical, you don’t need to give options to extend the time because those
situations are unavoidable. Examples include a time-based game or when there’s a
physical inventory that is being quickly depleted.

When you implement timed tasks in your app, be critical and find ways to improve
the experience by giving people more time or other options.

Introducing Time Configurability


In Chapter 8, “Operable — Movement & Timing”, you worked with the auto-advance
timer on the recipe cards in Taco Tuesday. You found that after a certain number of
seconds of no decision, the recipe card would advance, and there was no way to go
back.

raywenderlich.com 191
Android Accessibility by Tutorials Chapter 11: Designing for Neurodiversity

You added a toggle for the time limit to resolve the issue, putting the control into the
user’s hands.

There’s another option, which you’ll work with now: Make this time limit
configurable. Some users might appreciate a nudge if they haven’t made a decision.
Others will prefer more time to read and consider. Others might opt out of time
limits altogether.

You’ll add these options to Taco Tuesday. Start by adding the following to
strings.xml:

<!-- 1 -->
<string name="preference_seconds_title">Seconds for auto
advance</string>
<!-- 2 -->
<string-array name="time_options">
<item>10</item>
<item>15</item>
<item>20</item>
<item>30</item>
<item>50</item>
</string-array>

Here, you’re setting up resources for:

1. The title of the preference you’ll add to the settings screen

2. Seconds for the options of this preference

Next, go to root_preferences.xml. Below the SwitchPreferenceCompat with the


key value of auto_advance, add:

<ListPreference
android:defaultValue="15"
android:entries="@array/time_options"
android:entryValues="@array/time_options"
android:key="time_length"
android:title="@string/preference_seconds_title" />

This sets up a preference to use the resources you’ve created.

Finally, to put it all together, in DiscoverViewModel.kt, find fetchRandomTaco().


Find the top of the if block where you’re already checking shared preferences to see
if the auto advance is on.

raywenderlich.com 192
Android Accessibility by Tutorials Chapter 11: Designing for Neurodiversity

Add this statement within that if block:

val seconds = sharedPreferences.getString("time_length", "15")


?.toIntOrNull() ?: 15

This code fetches the set number of seconds from preferences, defaulting to 15 if it’s
unset.

To use this value, replace the call to delay() with:

delay(seconds * 1000L)

With this call, you convert seconds to milliseconds then set the length of time before
the app auto-advances to the next recipe.

Confirm that the updated section of the method looks like this:

if (sharedPreferences.getBoolean("auto_advance", false)) {
val seconds = sharedPreferences.getString("time_length", "15")
?.toIntOrNull() ?: 15
fetchTacoTimer = viewModelScope.launch(Dispatchers.IO) {
delay(seconds * 1000L)
fetchRandomTaco()
}
}

Build and run. Confirm that you have control when auto-advance is turned on and
that you can set the interval.

Setting that allows choosing the time limit.

Communicating with Clarity


Regardless of users’ abilities, you need to make two things clear: How to use the app
and what happens after taking an action. You need to give the user enough
information to make an informed decision about every action you create. Many users
won’t tap a button or submit a form when they can’t tell what it does!

raywenderlich.com 193
Android Accessibility by Tutorials Chapter 11: Designing for Neurodiversity

Buttons, in particular, can induce anxiety when they’re poorly explained. The user
may wonder if they get a confirmation screen after tapping “Submit” or if their card
was charged. Or if they’ll receive a barrage of spammy emails.

There are a few best practices to know:

1. Ask the user to confirm their choice, especially in a multi-step process.

2. Anticipate the questions a user might ask and build the answers into the app. For
example, “Are there more steps to complete the process, or is this the last one?”

3. Assume that features and next steps are unapparent to most users.

Any clarity you can provide will reduce cognitive overhead and give your user a
smoother, more enjoyable experience.

Clarifying When a Recipe is Saved


In Taco Tuesday, it’s unclear when it saves changes you’ve made to a recipe. You’re
left guessing. You can’t undo and there’s very little control. The only way to know is
to close the app and get back into the recipe.

In reality, the recipe saves when you leave the screen. This use case is an excellent
example of why you need to anticipate user questions. You’ll clarify the experience,
so the user isn’t left guessing.

Open strings.xml and add this resource:

<string name="recipe_detail_save">Details will be saved when


exiting the recipe.</string>

Now, open fragment_recipe_detail.xml. Add this text view above the


recipe_detail_made_it CheckBox:

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="@dimen/space_normal"
android:paddingBottom="@dimen/space_normal"
android:text="@string/recipe_detail_save"
android:textAppearance="@style/
TextAppearance.AppCompat.Caption" />

This logic informs the user when their changes are saved.

raywenderlich.com 194
Android Accessibility by Tutorials Chapter 11: Designing for Neurodiversity

Build and run. Open the first shown recipe’s details, make some changes to it, and
then observe the new message.

Note that details will save when closing the recipe.


There are more best practices you can lean on to improve your app’s clarity, for
example:

• Eliminate long blocks of text

• Explain images

• Limit distractions

Eliminating Long Blocks of Text


Unless you’re settling in to read a long-form article, you’re unlikely to read more
than a few lines of text. The same goes for your users.

Walls of text are hard to consume. They can feel like too much to process at once or
make somebody feel burdened. Text walls are also a great reason to get distracted
with another app. And let’s face it: They’re often poorly written. In particular, long
text blocks can be stressful for people with dyslexia, autism or cognitive decline.

In Chapter 9, “Understandable”, you touched on this when you reduced the text on
the discover screen, so it’s more appropriate for the role of the view.

When you’re preparing copy for your app, opt for short sentences, short words, clear
directions and bullet points instead of paragraphs.

You can also lean into diagrams and images when there is a lot of context to share.

raywenderlich.com 195
Android Accessibility by Tutorials Chapter 11: Designing for Neurodiversity

For many, diagrams are easier to process than walls of text.

Sad phone with lots of text.

Formatting Text
When you do have areas of text, format it such that:

• It’s justified towards the start of the screen.

• It’s free of unnecessary formatting such as underlining, italics or uppercase.

Removing these formatting attributes makes your text easier to read, especially for
users with dyslexia.

Explaining Images
When your app has images, it’s your job to enable the user to assign meaning to
them. Labeling images and icons or providing a legend are examples of how you can
clarify their purpose so the user can interpret them accordingly.

Everyone interprets images differently. Think about all the times you’ve seen a star
icon in an app. Does the star indicate a way to rate something? Or does it favorite
something? Does it give you a badge or add something to a private list? Without an
explanation, some users will never understand this poor star’s purpose!

Each user has a different ability to assign meaning to imagery. The better you
describe these images, the clearer your app will be, and the less likely your user will
get distracted or discouraged from using your app.

raywenderlich.com 196
Android Accessibility by Tutorials Chapter 11: Designing for Neurodiversity

Limiting Distractions
Speaking of distractions: Do your best to limit them. Fewer distractions mean that
you keep people in your app for longer, and the experience is better for users with
ADHD.

Distractions can include a popup or something that branches off the main flow of
your app. Another example could be that the user has to close the app to adjust a
setting before using it. Distractions can become points of friction in your UX.

When building an experience, think about points of friction and if the user benefits
more from branching off to other tasks or staying focused on the task at hand.

Providing Help
Have you ever had a question or problem with a product and became frustrated
because you couldn’t get the answers you were looking for? A point of frustration is
an example of friction.

Reduce friction in your app by making help readily available, and don’t make users
jump through hoops to get answers. Hunting around for help can trigger anxiety or
discourage someone from using your app.

You can add help inline, as an FAQ, or as a help center with access to avenues like
email, chat and calls. Whatever option you implement should be easy to find and
access.

Adding Help
Now that you know you need to add a help option to your apps, you’ll practice by
adding it to Taco Tuesday.

Open root_preferences.xml. Within the PreferenceCategory under the help


header, add the following:

<PreferenceScreen
android:title="@string/preference_book_forum_title">
<intent
android:action="android.intent.action.VIEW"
android:data="https://forums.raywenderlich.com/c/books/
android-accessibility-by-tutorials/74" />
</PreferenceScreen>

raywenderlich.com 197
Android Accessibility by Tutorials Chapter 11: Designing for Neurodiversity

This code adds an option to the settings screen that allows the user to post on a help
forum for this book.Build and run to see this change.

View forum setting.

Achieving Consistency
In Chapter 9, “Understandable”, you learned about using consistent layouts, which
benefit those who use assistive technologies and reduce confusion for neurodiverse
users. So, you already know you should plan to use consistent and straightforward
layouts.

You want each part of your app to be as predictable as possible, with similar
elements performing similar behaviors regardless of where they’re used.

Similarly, you also want to be able to expect changes in context. Don’t change to a
different screen or context without user action unless you let them know about it
first. Otherwise, the change could confuse the user about where they are in the app
and how they got there.

Minding Your Phrasing


Language and phrasing significantly impact your app’s user experience. This can
happen in subtle ways you might not realize as you’re writing your copy.

When you’re careless about the words you use, your copy could be misunderstood. In
other cases, your words can negatively impact users.

Providing Consumable Language


Here are three best practices to follow:

• As noted in Chapter 9, avoid figures of speech, jargon, idioms and complex


language.

• Be descriptive and succinct.

• Use simple words.

raywenderlich.com 198
Android Accessibility by Tutorials Chapter 11: Designing for Neurodiversity

People on the autistic spectrum or who do not use English as a first language may
interpret phrases in your app literally. Read the copy in your app through a literal
filter to see if it makes sense.

And if you’re having trouble “wrapping your head around that”, maybe that’s
because skulls are rigid and aren’t meant to wrap around things. Please don’t give
yourself a concussion trying. (See what I did there?)

Using Inclusive Language


Derogatory language has no place in most apps. Make your copy inclusive of all
people, regardless of who they are.

This includes ability. For example, don’t use terms like “crazy” or “idiotic”, as these
are derogatory words for people with disabilities. Use terms such as “outrageous” or
“misguided” instead.

These shifts in your language remove some of the ableism, and they make your
message more precise and descriptive.

Other words to avoid are more nuanced, such as “easy”, “clearly” and “just.”
Something easy or clear for one user could trigger anxiety for another. When you say
to “just” follow this instruction, you imply that it is easy for everyone.

The wrong words can be incredibly discouraging and make your user feel excluded.
Make your user feel welcome by using inclusive language.

Giving Alternatives
An underlying theme in this book is to allow users to consume your content in
multiple ways. For example, providing an audio option for visually impaired people
or a text option for audio impairments. Graphics and video can also be useful
alternatives.

Giving options also makes your app more usable for people with dyslexia.

There are more options you can provide. One example is reminders. Especially useful
for a multi-step process, prompts help the user remember content from previous
pages.

Whenever possible, allow users to input inaccurate spelling. Even with


autocomplete, it’s easy to misspell words. Unless correct spelling is critical for the
app, try to find a way to accept inaccuracy.

raywenderlich.com 199
Android Accessibility by Tutorials Chapter 11: Designing for Neurodiversity

Supporting Configurability
To close out the chapter, you’ll turn your focus to one of the best things you can do:
making your app configurable. Each user has unique needs and preferences. Some
people need light mode while others need dark. Some prefer text labels and other
logos. Some want confirmation for everything, and others prefer fewer clicks.

Adding configurability allows your app to meet the needs of more people. This gives
all your users a more tailored, and therefore enjoyable, experience.

Adding a Dark Mode Option


To demonstrate the concept of configurability, you’ll allow the user to toggle
between dark and light mode directly from Taco Tuesday.

Open root_preferences.xml, and add this to the Display PreferenceCategory:

<SwitchPreferenceCompat
app:key="dark_mode"
app:title="@string/preference_dark_mode_title"
app:useSimpleSummaryProvider="true" />

This block allows the user to set the dark mode preference on the settings screen.

Next, open SettingsFragment.kt. Add this to the bottom of


onCreatePreferences():

findPreference<SwitchPreferenceCompat>("dark_mode")
?.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, newValue ->
AppCompatDelegate.setDefaultNightMode(
if (newValue == true) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_NO
}
)
true
}

You’ve set a listener on the dark mode setting so that when the user changes the
setting on their device, it’s immediately reflected in the app’s color scheme.

raywenderlich.com 200
Android Accessibility by Tutorials Chapter 11: Designing for Neurodiversity

Finally, open TacoTuesdayApp.kt. Add SharedPreferences as a property:

@Inject
lateinit var sharedPreferences: SharedPreferences

You’re injecting SharedPreferences to use in the next step.

At the bottom of onCreate(), delete the lines:

AppCompatDelegate.setDefaultNightMode(
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)

And replace them with:

AppCompatDelegate.setDefaultNightMode(
if (sharedPreferences.getBoolean("dark_mode", false)) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_NO
}
)

Now, when the app starts, the color scheme will be set according to the preferences.

Build and run. Toggle this setting and confirm that it’s working correctly.

Dark mode setting.

raywenderlich.com 201
Android Accessibility by Tutorials Chapter 11: Designing for Neurodiversity

Key Points
• Being inclusive of neurodiverse users makes your app better for everyone.

• Reducing time constraints can reduce user anxiety.

• Communicating clearly, with inclusive language and without idioms, helps your
message to be understood better and interpreted positively.

• Reading long blocks of text is difficult for many users.

• Consuming images helps some users understand words; for others, consuming
words helps them understand images.

• Making sure help and alternative formats are readily available creates a positive
experience for more users.

• Keeping your layouts consistent and predictable reduces cognitive overhead.

• Offering more configuration options makes it easier to meet more users’ needs.

Neurodiversity is often overlooked in the already neglected topic of accessibility.


Congrats to you for learning about how to improve your apps in this way!

Where to Go From Here?


All of these guidelines and best practices can be hard to remember. For a visual
reminder, check out these posters (https://accessibility.blog.gov.uk/2016/09/02/dos-
and-donts-on-designing-for-accessibility/).

You can also use the accessibility checklist found at the end of this book.

raywenderlich.com 202
12 Chapter 12: Getting Your
Team on Board
By Victoria Gonda

Now that you believe that accessibility is essential, what’s next? You know where to
start and how to improve your app’s accessibility. But how can you get buy-in from
your team to dedicate time to accessibility? How do you share what you’ve learned
and inspire your colleagues to do the same?

On many teams, accessibility is a second thought, if it’s even thought about at all. It
can be a challenge to find time to make these improvements.

The answer varies from team to team and company to company and depends on
these groups’ motivations.

In this chapter, you’ll develop a plan for your specific situation as you read. There is
no coding in this chapter, so grab a pen and paper or open a new notepad so you can
capture your ideas in real-time.

raywenderlich.com 203
Android Accessibility by Tutorials Chapter 12: Getting Your Team on Board

Recognizing a Need
Before you approach your team, you need a rough idea of your app’s accessibility and
how much attention the company pays to accessibility. If your team already has an
accessible app, you might be one of the lucky few that don’t need to budget a lot of
time to improve it.

This step doesn’t require a full audit of your app. Instead, you can do a quick pass
with an accessibility scanner and TalkBack to estimate your level of compliance.

Act: Schedule a short amount of time to skim your app for accessibility issues
using Accessibility Scanner and TalkBack. If you have limited time, commit to
a short 20-minute session to take notes and get a feel for the accessibility of
your app.

It might also be helpful to speak to your colleagues to discover existing accessibility


efforts or programs. If they exist, you can engage the people involved and gain
momentum together. It’s helpful to have people on your side when encouraging
change in your organization.

Act: Take note of who to talk to in your company to learn about existing
efforts. Make a plan for when and how to approach them. Remember that your
prime objective at this stage is to understand what’s there. You’ll construct a
strategy for inspiring the needed change later in this chapter.

Once you have an idea of the app’s compliance level, your organization’s dedication
to accessibility, and who might be interested in supporting your goals, you can start
thinking about if changes are necessary and how to set the change in motion.

Getting Buy-In
There’s a good chance that you’ve already identified a need for improvement. Now
comes the hard part: influencing that change. The first two actions you can take to
start encouraging change are:

1. Educate others.

2. Make accessibility needs more visible.

raywenderlich.com 204
Android Accessibility by Tutorials Chapter 12: Getting Your Team on Board

Educating Yourself and Others


Because most companies place minimal emphasis on accessibility, there is also
spotty knowledge sharing about how to address it. Most of your colleagues don’t
know what it means to build an accessible app or why it’s important. This is where
you come in.

You can help your team learn about this topic. You can share tips you learned in your
syncs, watch a talk on accessibility in a team meeting, or organize a book club
around this book.

Plug into how your team already learns about new topics and try to integrate it there.
Once the learning starts, there will be people on your team who are as excited about
accessibility as you.

Note: If you’re looking for a talk to watch with your team, check out ‟Increase
Your Product Quality Through Accessibility” (https://www.raywenderlich.com/
10528194-increase-your-product-quality-through-accessibility) from RW
Talks.

When you’re sharing knowledge and trying to recruit people to your cause, you need
to understand each person’s motivations. Once you know that, you can make a case
around the specific aspects of accessibility that benefit them. For example:

• If someone is motivated by profit, focus on how it can increase profitability.

• If they care about user experience, show how accessibility makes a better product
for all users.

• If they care about developer productivity, inform them of the efficiencies of


building an accessible app.

There are many benefits to building an accessible app, including:

• Widening your audience.

• Avoiding legal battles.

• Making a better product.

• Driving innovation.

• Increasing developer productivity.

raywenderlich.com 205
Android Accessibility by Tutorials Chapter 12: Getting Your Team on Board

• Recognizing revenue potential.

• Treating others with care.

If you need a refresher on any of these points, go back to Chapter 1, ‟Why


Accessibility”.

Act: Who do you need to educate about accessibility on your team? What are
their goals when they make decisions? Take notes and use your thoughts to
inform a plan to help your colleagues learn how compliance can help the
product.

A final tip when you’re educating your team: The way you share information makes a
difference. Statistics can be convincing but know that data alone is not enough to
change minds. You’ll be most effective when you mix stories and data. Stories elicit
emotions, and emotions change minds and help your argument stick.

Bringing Visibility to the Need


Even after people are educated and on board with improving accessibility, it is still
easy to overlook. How can you keep it top of mind?

One way is to sprinkle small reminders and sustainable habits through your day.

If you get an inaccessible design, ask if you can see an alternative that accounts for
accessibility. When you’re reviewing code and see something making the app more
accessible, congratulate the author. If you learn a new accessibility tip, share it with
your team.

You can also advocate for the time in your development cycle to dedicate to
accessibility. This could look like making sure accessibility tickets are included in
each sprint or including accessibility review in QA. It’s okay to start small here. Every
little bit helps.

raywenderlich.com 206
Android Accessibility by Tutorials Chapter 12: Getting Your Team on Board

Expecting Pushback
You should expect and prepare for people to push back. People will disagree with
you. Be patient and don’t give up when someone dismisses you or casts doubt on
your ideas. Put in an effort to address your colleagues’ objections with poise.

One objection you’re likely to encounter is that spending time on accessibility will
slow the team down. This is a valid concern. You must be able to continue moving
the product forward. You can still mitigate this concern.

Review the points in Chapter 1, ‟Why Accessibility”, that show how accessibility
saves time and money over the long term. Try applying these to make a case that the
time upfront is worth it for the company.

You can always compromise on how much time to dedicate to accessibility. If you’re
initially only able to spend a little time on improving accessibility, that’s a win. Even
minor improvements will have an impact on the people they benefit.

Scaling Support
You might be wondering how you can scale your accessibility support. You need to
keep moving your product forward, even as it or your team increases in size, right?
Scaling up your support without interfering with progress is a valid concern.

You have options for how to scale up your team’s knowledge and skills. By combining
options that work well for your team, you can ease the burden and make it possible
to build out your app without exerting a disproportionate amount of energy to
support it.

In many cases, scaling will start with you. Focusing on incremental improvements
over large changes, integrating accessibility into your processes, and sharing
enthusiasm with your teammates are the keys to scaling.

raywenderlich.com 207
Android Accessibility by Tutorials Chapter 12: Getting Your Team on Board

Staying Focused and Starting Small


You could feel overwhelmed by the amount of work to do, especially when dealing
with a legacy app with much room for improvement.

Try to break tasks down and focus on one small bit at a time. Maybe that means you
only work with one screen or view within the screen at a time. Or, you could focus on
one criterion at a time.

The key point is that you don’t need to do it all at once. Little improvements add up
over time. Find a strategy to break down the work that works well for your team.

It’s hard to get buy-in when you’re asking people to do a lot of work or substantially
change their work habits. You’ll find that it’s much easier to get people on board
with you when what you’re asking doesn’t feel like a large, imposing change.

Act: Using the information you gathered during the rough scan of your app,
think about how to break down these chunks of work into small tasks that
would fit into your team’s workflow and processes.

Integrating into your Process


You can also lean into your existing processes and automation to keep accessibility
top-of-mind and reduce the burden on your team.

Find ways to use what you already have:

• Do you have a PR template? Add an accessibility reminder, checklist or


explanation step.

• If you have a success criterion template, add a note there.

• Include accessibility checks in your QA step.

• Create and include accessibility improvements in your sprint planning.

If you have automation, you can also add accessibility checkpoints there. You can
make sure you have accessibility linters turned on and required to pass for new code.
Set up Espresso accessibility checks. Use the Google Play Console pre-launch reports
to uncover accessibility issues in your app.

raywenderlich.com 208
Android Accessibility by Tutorials Chapter 12: Getting Your Team on Board

Be creative about the ways you can improve your automation and processes!
Remember to get input from your team as you think through how to integrate
accessibility into your workflow. Your colleagues may surprise you with innovative
ideas you would not think of, and people are more likely to support new ways of
doing things when their ideas become a part of the solution.

Act: Take note of what processes and automation your team uses and how you
can introduce accessibility reminders and tasks. Take note of who owns or
benefits the most from current processes so that you know who is most
important to consult as you develop your plan.

Sharing Enthusiasm
When you’re the only person championing accessibility, you can get burnt out
quickly. With some teams, it can take a lot of energy to change hearts and minds.

Find the other people who are enthusiastic about accessibility and try to get them
excited before moving on to the others. It’s easier to create a culture of accessibility
when you have multiple people on your side.

One tactic that works well to build excitement comes up during code reviews — in
these rare moments, you have a captive audience and the ideal context to bring up
accessibility. Make the most of these moments by giving feedback on how well it
complies. When a teammate makes something that is accessible, praise them and tell
them why what they did was positive.

If there’s room for improvement, gently nudge them in the right direction. When you
give feedback, remember there are many aspects to making an app accessible, and
you and your teammates won’t always get it right on the first try.

Tracking Improvement
If your company relies on A/B tests or other analytics to inform decisions, someone
on your team will probably ask about user tracking.

When considering what to track, don’t even consider monitoring if a person uses
accessibility services without their knowledge. This is an invasion of privacy. Ideally,
you should never track this behavior. If you do, make sure it’s consensual.

raywenderlich.com 209
Android Accessibility by Tutorials Chapter 12: Getting Your Team on Board

Tracking this information also gives you unreliable data. Some people use
accessibility services to turn on their devices or grant permissions to apps such as
password managers. Many people would benefit from an accessible app but don’t use
accessibility services.

You can still track other indicators. Perhaps one of the most important things to
track is your legal compliance.

You can go through a company to measure this or use the Accessibility Scanner or
Espresso checks to create a system of measures for some issues.

You can also measure the types of accessibility-related support tickets. This is an
example of a qualitative measure. Do any of the tickets suggest people are trying to
use accessibility services with your app? Or are the tickets eerily devoid of such
issues? How many similar tickets are there? Review and group similar tickets and
track how many come in week over week for each type. Over time, you’ll see how
changes you make affect the user experience and identify opportunities for further
improvements. And you’ll have user-based data and insights to back you up.

Finally, you can A/B test some accessible features, but take caution with this tactic.
An unfavorable result isn’t a valid reason to move away from accessibility; adverse
results usually indicate an opportunity for improvement. Some people will even
interpret failure as proof that accessibility is a waste of time. Use the insights you
gain from the experiment to try something else. There are many paths to
compliance.

raywenderlich.com 210
Android Accessibility by Tutorials Chapter 12: Getting Your Team on Board

Key Points
• Understand your company’s approach to accessibility before taking action.

• Help your teammates understand the importance of accessibility and how to make
your app accessible.

• Keep a person’s role in mind when educating them.

• Know that it’s normal to experience pushback.

• Believe that it’s better to accomplish a little than nothing at all.

• Find simple, repeatable, contextual ways to build accessibility in your existing


processes.

• Encourage enthusiasm on your team.

• Track metrics and measures, but don’t invade people’s privacy by tracking who
uses accessibility services without express consent.

Where to Go From Here?


Congratulations! You’ve reached the end of the book. You’ve learned why
accessibility is essential, how to make your app more accessible and how to get your
team on board — pat yourself on the back.

You’re not done yet. Working towards accessibility is a continual process. You’ll get
code or design wrong and learn something new. You’ll come across an entirely new
situation in an app to try to figure out how to make compliant. You’ll work with
someone new who you can help educate. A new accessibility service will become
available. Be patient with yourself as you go through this journey.

As you start applying your knowledge to your day-to-day work, use the headers in
this chapter to help you plan. Remember to be patient with others. You can also use
the checklist in the appendix in the back of this book to remind you what to watch
for and as a starting place for a custom checklist for your own team.

raywenderlich.com 211
13 Conclusion

What an amazing experience it’s been! You’ve learned why designing your apps with
accessibility in mind is so beneficial and how to improve the experience that users
have with your app. You’ve tried many techniques to make apps more operable,
understandable, and robust. You’ve learned how to design your app to meet the
guidelines of WCAG. Most importantly, you’ve shared the experience of your app
from your users’ perspective. And now that you understand the importance of
designing apps for accessibility, you’ve learned some great tips for bringing your
team on board and integrating accessibility into your team’s processes.

By putting the book concepts to practice, your apps will become easier to use and
understand for all users. Not only that, but you’ll rest easy knowing your app meets
the guidelines for accessibility.

We hope the ideas you saw in this book inspire you to incorporate accessibility
practices into your app and inspire your team and community to do the same!

If you’re really excited about accessibility we recommend Victoria’s screencast


Increase Your Product Quality Through Accessibility (https://
www.raywenderlich.com/10528194-increase-your-product-quality-through-
accessibility). If you’re looking for more books to enhance your Android
development skills, we recommend Real-World Android by Tutorials. If you’re newer
to Android, we recommend checking out Android Apprentice.

raywenderlich.com 212
Android Accessibility by Tutorials Conclusion

If you have any questions or comments as you work through this book, please stop by
our forums at https://forums.raywenderlich.com and look for the particular forum
category for this book.

Thank you again for purchasing this book. Your continued support is what makes the
books, tutorials, videos and other things we do at raywenderlich.com possible. We
truly appreciate it!

– The Android Accessibility by Tutorials team

raywenderlich.com 213
Section II: Appendix

raywenderlich.com 214
A Appendix A: Accessibility
Checklist
By Victoria Gonda

Use these checklists to remind you what to look out for in your app. You can also pick
and choose items for an audit, QA steps, or a PR checklist. While these lists don’t
cover all the guidance from WCAG, they provide a good overview of the more
common items you’ll see on Android.

Each item references the chapter in this book that covers the topic, so you can easily
find where it is in the book.

Quick Peek Checklist


Use this abbreviated checklist when you only have time to do a quick, initial pass.
These are often quick wins and might work well for a PR checklist.

• Images and icons have content descriptions. “Chapter 2, Hello, Accessibility!” and
“Chapter 4, Perceivable — Layout & Labeling”.

• Screen orientations are supported. “Chapter 4, Perceivable — Layout & Labeling”.

• Inputs are labeled. “Chapter 4, Perceivable — Layout & Labeling” and “Chapter 9,
Understandable”.

• Text is scalable. “Chapter 4, Perceivable — Layout & Labeling”.

• Instructions don’t rely on characteristics such as size, shape and color. “Chapter 5,
Perceivable — Time-Based Media & Cues”.

raywenderlich.com 215
Android Accessibility by Tutorials Appendix A: Accessibility Checklist

• Text and icons have adequate color contrast. “Chapter 6, Perceivable — Colors”.

• Touch targets are at least 48dp by 48dp. “Chapter 7, Operable — Navigating the
Screen”.

• There is no flashing. “Chapter 8, Operable — Movement & Timing”.

Image of the abbreviated checklist.

Thorough Checklist
Use this checklist when you’re doing a full audit or are trying to remember a rule.

• Images and icons have content descriptions. “Chapter 2, Hello, Accessibility!” and
“Chapter 4, Perceivable — Layout & Labeling”.

• Clickable views are also focusable. “Chapter 2, Hello, Accessibility!”.

• Headers are labeled. “Chapter 4, Perceivable — Layout & Labeling”.

• Views are laid out logically and predictably. “Chapter 4, Perceivable — Layout &
Labeling”.

• Related items are grouped. “Chapter 4, Perceivable — Layout & Labeling”.

• All screen orientations are supported. “Chapter 4, Perceivable — Layout &


Labeling”.

• Inputs are labeled. “Chapter 4, Perceivable — Layout & Labeling” and “Chapter 9,
Understandable”.

raywenderlich.com 216
Android Accessibility by Tutorials Appendix A: Accessibility Checklist

• Text is scalable. “Chapter 4, Perceivable — Layout & Labeling”.

• Time-based media has alternatives and is controllable. “Chapter 5, Perceivable —


Time-Based Media & Cues” and “Chapter 8, Operable — Movement & Timing”.

• Instructions don’t rely on characteristics such as size, shape and color. “Chapter 5,
Perceivable — Time-Based Media & Cues”.

• Text and icons have adequate color contrast. “Chapter 6, Perceivable — Colors”.

• Support dark mode. “Chapter 6, Perceivable — Colors”.

• All items are reachable via keyboard navigation. “Chapter 7, Operable —


Navigating the Screen”.

• Content descriptions are unique. “Chapter 7, Operable — Navigating the Screen”.

• Focus order preserves meaning. “Chapter 7, Operable — Navigating the Screen”.

• The purpose of links is clear. “Chapter 7, Operable — Navigating the Screen”.

• Gestures have one-tap alternatives. “Chapter 7, Operable — Navigating the


Screen”.

• Touch targets are at least 48dp by 48dp. “Chapter 7, Operable — Navigating the
Screen”.

• Allow adjustable timing. “Chapter 8, Operable — Movement & Timing”.

• There is no flashing. “Chapter 8, Operable — Movement & Timing”.

• Support right-to-left layouts. “Chapter 9, Understandable”.

• The language is clear. Avoid idioms and jargon, and explain abbreviations.
“Chapter 9, Understandable” and “Chapter 11, Designing for Neurodiversity”.

• Navigate consistently. “Chapter 9, Understandable”.

• Provide support for errors. “Chapter 9, Understandable” and “Chapter 11,


Designing for Neurodiversity”.

• Use system views when possible. “Chapter 10, Robust”.

• Custom views communicate with accessibility services. “Chapter 10, Robust”.

raywenderlich.com 217

You might also like