Logo

dev-resources.site

for different kinds of informations.

Support Time to Take Action with Compose

Published at
12/28/2024
Categories
android
a11y
programming
mobile
Author
eevajonnapanula
Categories
4 categories in total
android
open
a11y
open
programming
open
mobile
open
Author
15 person written this
eevajonnapanula
open
Support Time to Take Action with Compose

While working on my master's thesis and the Android Accessibility Checklist, one of the answers to my survey mentioned an accessibility setting called time to take action. Since then, I've been curious about it and wanted to write a blog post as I feel it's one of the undersupported accessibility settings and really useful for those who utilize it.

So, what is time to take action, and why would someone use it? And why should we, as developers, care? Let's talk about that first.

Time to Take Action

Time to take action is a setting that controls the minimum time in which temporary messages asking a user to take action are shown. So, for example, when you press the volume buttons on your Android phone, you should see the volume controls next to the volume buttons, and this setting controls how long they're visible.

This setting has different options: Default, 10 seconds, 30 seconds, 1 minute and 2 minutes. You can find them from Settings -> Accessibility Settings -> Timing controls -> Time to take action (Accessibility timeout). The screen looks something like this, depending on your phone's version and manufacturer:

Time to take action-settings screen from Pixel phone with an illustration and the following options visible: Default (selected), 10 seconds, 30 seconds.

And why would someone need this setting? Well, the source code and documentation for a method we're going to use in a moment puts it pretty well:

Some users may need extra time to review the controls, or to reach them, or to activate assistive technology to activate the controls automatically.

Okay, now we've established what the time to take action is. However, the question of relevance remains: Why should we care as developers? Isn't it something that the operating system handles automatically?

The answer is yes and no. Most components on the operating system level and Material3 components respect this setting. However, when you're building a custom component, it's not automatically respected, and you'll need to add support for it. That's why the settings page mentions that not all apps support the setting. The thing is, developers usually don't know about it.

Let's next talk about how to support time to take action-setting with a custom component.

How to Respect Time to Take Action?

For the sake of example, we'll build a small tooltip component with a button to close it. The tooltip disappears after the minimum time to take action if the user does nothing. The default value, in our case, is set to 10 seconds.

Before diving into code, here's a video where the tooltip is first shown with the time to take action setting with a default value, and then it's set to 30 seconds:

This example doesn't contain all the code (like the tooltip content), just the relevant parts. As seen in the video, the tooltip becomes visible after the user clicks an "Info"-button, then is visible for the required time, depending on the time to take action-setting, and finally, disappears. The tooltip contains a button to hide the tooltip faster.

We're adding the support for time to take action in two steps:

  1. Calculate the delay for hiding the tooltip
  2. Hide the tooltip after the calculated time has passed

The first step is to calculate the delay, or tooltipTimeout, as we're calling it in the code:

@Composable
fun Tooltip(
    tooltipVisible: Boolean,
    hideTooltip: () -> Unit,
    modifier: Modifier = Modifier
) {
    val tooltipTimeout = LocalAccessibilityManager.current?
        .calculateRecommendedTimeoutMillis(
             originalTimeoutMillis = TOOLTIP_DEFAULT_TIMEOUT_MS,
             containsText = true,
             containsControls = true,
         ) ?: TOOLTIP_DEFAULT_TIMEOUT_MS

    ...

    TooltipContent(...)
}

// 10 seconds
const val TOOLTIP_DEFAULT_TIMEOUT_MS = 10000 
Enter fullscreen mode Exit fullscreen mode

LocalAccessibilityManager composition local provides a neat function for calculating the timeout, so we use that.
The first parameter for calculateĀ­RecommendedĀ­TimeoutĀ­Millis is the original timeout milliseconds, which applies when there are no accessibility timeout needs. The other parameters are a bunch of boolean values informing about the element's contents for which the timeout value is being calculated. These are about whether the element contains text, controls, or icons.

The calculateĀ­RecommendedĀ­TimeoutĀ­Millis returns the recommended timeout time as Long. As the AccessibilityManager might not be available in some operating systems or OS versions and thus is nullable, we also need a default value. This value is the TOOLTIP_DEFAULT_TIMEOUT_MS in our code - the same one we use for the original timeout. In the example, the value is 10 seconds.

Next, we'll use the freshly calculated timeout:

@Composable
fun Tooltip(...) {

Ā  Ā ... 

Ā  Ā Ā LaunchedEffect(tooltipVisible) {
        if (tooltipVisible) {
            delay(tooltipTimeout)
            hideTooltip()
        }
Ā  Ā Ā }

    TooltipContent(...)
}
Enter fullscreen mode Exit fullscreen mode

So, what happens in the code snippet is that whenever the tooltipVisible-value changes, we check if the change was for making the tooltip visible, and if so, then we first delay for the number of milliseconds we calculated in the previous step and then hide the tooltip.

This way, we can respect the user's settings for elements that they might need more time to interact with.

Wrapping Up

In this blog post, we've discussed the time to take action setting, what it is, why developers should know about it, and how to respect it. We've done this by building a tooltip component, which hides after a certain amount of time.

Did you know about this setting? Have you ever implemented support for it? If so, what kind of UI components were they?

Links in the Blog Post

a11y Article's
30 articles in total
Favicon
Why are we so rubbish at accessibility?
Favicon
Web Accessibility: Who's it for?
Favicon
I Created VanillaHTML (a CSS File)
Favicon
Leveraging AWS Services for Accessible Cloud Solutions
Favicon
Preparing your business for the European Accessibility Act
Favicon
How to Automatically Generate Alt Text for Images Using Amazon Rekognition
Favicon
Support Time to Take Action with Compose
Favicon
Web Development in Healthcare: Compliance and Best Practices for Healthcare Websites
Favicon
Mobile Accessibility Advent Calendar Part 2
Favicon
Inclusive Design: How to Build Web Applications That Welcome Everyone
Favicon
Accessible Color Contrast: Why It Matters and How to Get It Right
Favicon
a11y. CĆ³mo solucionar los 6 errores mĆ”s comunes de accesibilidad web
Favicon
Making Accessible Links in SwiftUI
Favicon
Native HTML: Accordion Revisited
Favicon
5 accessibility defects LinkedIn could resolve to make content more accessible
Favicon
User-Centered Design: The Secret to Intuitive, User-Friendly Interfaces
Favicon
Mobile Accessibility Advent Calendar Part 1
Favicon
Top 10 Web Accessibility Mistakes Developers Make and How to Avoid Them
Favicon
šŸš€ React Best Practices for Scalable Frontends: Part 3 ā€“ Lazy Loading and Accessibility
Favicon
WICK-A11Y 1.4.0: Not Everything Needs to Fail a Test!
Favicon
Introduction to ARIA: A Developerā€™s Guide
Favicon
Balancing Visual Design and Optimization in Front-End Development
Favicon
How to Test Web Accessibility Using the WAVE Tool: A Beginner's Guide
Favicon
Building Accessible Forms: Best Practices for Usability
Favicon
Accessibility on web
Favicon
Automated Testing with jest-axe
Favicon
Accessible Input Elements | the Basics
Favicon
Accessible, sustainable, and creative web development
Favicon
Accessibility (a11y) Rules - 3
Favicon
Accessibility (a11y) Rules - 4

Featured ones: