Android, Animations and Reduced Motion

Reading time: about 4 minutes

Published

Android, Animations and Reduced Motion.

I don't like animations, and I'm not alone. The Verge published an article by s. e. smith: My war on animation as part of their Accessibility week, and I loved it. I was able to relate to that article on so many levels.

For me, animation and motion on a website or app can be a problem for two reasons: They might make me physically sick and distract me. Especially when I'm tired, distraction is a huge problem.

So, now you might wonder, how can I survive the internet today? Animations are everywhere.

There's an app for that! Or, rather, a setting. I can turn motion off (or reduce it) with operating system settings on my phone and computer. When this setting is on, operating system level animations are turned off.

How about websites and apps, then? Do they respect that setting? Yes and no. It entirely depends on the developers implementing the reduced motion-media query on the web. On the other hand, in apps, it depends on how the animations are built.

In this blog post, I'm talking about Android animations and how to respect that setting. I also discuss when you need to implement the check and when the animations are turned off by default.

But first, let's talk a bit about why you should care about respecting that setting.

Why is this Important?

It's the right thing to do. I mean, users have expectations on how apps work, and one of these expectations is that operating system-level settings are respected.

Sometimes not respecting that setting creates inconveniences, but sometimes it's about real, life-affecting symptoms that might get triggered. Nobody enjoys having a migraine or feeling sick after encountering something unexpected in the app - something that could have been prevented with a few lines of code.

I know there's not much knowledge about the need for reduced motion. I've worked with multiple devs, designers, and product people who've had no idea about that. And animations are here to stay - they drive engagement (or that's what everyone keeps telling me), and some people like them. But I just hope "engagement" won't drive over the accessibility needs of the people - so that's why I'm trying to educate everyone about this topic.

When to Check the Reduced Motion Setting in Your Code?

Reduced motion (or, animations off) -setting affects all Animator-based animations. That means most of the animations you use are turned off by default. The other week, I was developing a feature that required me to turn that setting off because of the animations. I was surprised by how much motion and animation was being turned off by that setting!

Also, when creating animations with Jetpack Compose, its animation classes follow that setting from version 1.2.0. However, if you're using earlier versions, I'd recommend testing if the setting is respected out of the box.

Another case when you need to know how to check if the reduced motion setting is on is if you're using something like Lottie-animations. I love how Lottie's Android component checks for reduced motion and displays the first frame if it's on - and all of this, out of the box.

However, sometimes the first frame is not applicable. Often animations start with an (almost) empty screen, which is not what you want to show users with reduced motion. So in these cases, checking if reduced motion is on and displaying a static image instead is the way to go.

So, there's no need for extra checks in many cases - at least if you're using the latest versions of, e.g., Compose. However, testing is the key. You can turn the reduced motion setting on from the accessibility settings - the setting is called "Remove animations," and depending on your phone, it might be under "Display" or "Visibility enhancements" or other similar.

How to Detect if Reduced Motion is Enabled

Since Android doesn't expose the value for reduced motion the same way as other accessibility services, such as if a screen reader is enabled, we need to be a little creative.

One way to deduce if reduced motion is enabled is to check the animation duration scale. We can get that value with

Settings.Global.getFloat(
  context.contentResolver,
  Settings.Global.ANIMATOR_DURATION_SCALE
)

The animation duration scale is 0f if reduced motion-setting is enabled.

However, if the reduced motion setting is not enabled, that setting can be undefined. So, to check the value, we'll need a catch-block, where we set the value to basically anything than 0f:

val animationDuration = try {
  Settings.Global.getFloat(
    context.contentResolver,
    Settings.Global.ANIMATOR_DURATION_SCALE
  )
} catch (e: Settings.SettingNotFoundException) {
  1f
}

Finally, to check if reduced motion is enabled, we can check if the animation duration is 0f. Here's the complete function for that:

fun isReducedMotionEnabled(): Boolean {
  val animationDuration = try {
    Settings.Global.getFloat(context.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE)
  } catch (e: Settings.SettingNotFoundException) {
    1f
  }
  return animationDuration == 0f
 }

Wrapping Up

So, even though most animations on Android respect the reduced motion setting out of the box, it's good to be aware of the possibility of situations when it needs to be respected.

I hope you've learned something from this blog post, and in the future, remember that animations are only a delight for some.

Read More