AnimatedIcons / Animation

AnimatedIcons: Radio Button

There is a nice micro-animation library at which contains some useful animations which are particularly well suited for animated icons. These are all free to use and downloadable at Lottie animations. For those that already use Lottie they can use these animations as-is. However using them is apps which don’t use Lottie, or in cases where they may need tweaking and you don’t have a designer available that can perform the necessary tweaks in After Effects, it may not be possible to do this. In this occasional series we’ll look at how to create some of these animations as Animated Vector Drawables which will show some useful AVD techniques.

The icon we’re going to look at this time is a design for a Radio Button which transforms from a simple circle in the unchecked state to a ticked box. There is an initial push in effect, then outline of the circle parts to enable the growing tick to expand outside the circle.

Let’s begin by considering the outer circle itself. Those that have followed the articles in this series may be able to guess that the parting of the circle is achieved by manipulating the trimPathStart and trimPathEnd values of the stroke path of the circle. But to achieve this we need to start and end the circle path at the point where the tick will cross it. It feels like we’ll need to use some maths to calculate this location on the canvas, but we can cheat! Let’s look at the vector for the checked state:




There are three components here, there’s an outer group which will become important later on, then two separate paths for the circle and the tick. The pathData for these on their own would actually render as this:

The circle is drawn from the topmost point in the centre, and the asymmetric trimPathStart and trimPathEnd values divide the path from the top centre. The tick is rendered almost vertically to pass through this gap. This keeps the pathData of both fairly simple. The trick is that the outer group also has a 45º rotation around a centre pivot point, and so the complete image is rendered as this:

Not only does the group perform this rotation, it also is the enabler for the push animation at the beginning of the transition:



This animator animates the scaleX and scaleY attributes of this group to perform an initial shrink then return the the original size to create this push in effect. The pivot point that was set on the group works for both the static rotation that we used earlier is the same for this scaling. We use keyframes within propertyValuesHolders for each of these attributes to perform this push in and back out again within the initial 40% of the animation, then holds them static for the remainder. The animations on the other components of the vector drawable will be running during the second half of the overall animation.

We use a similar technique to animate both the trimPathStart and trimPathEnd attributes of the circle path to perform the parting of the circle:



Once again we use keyframes to control the timing of when the animations occur. For both attributes they are held static for the first 50% of the animation, then they both transition to their open positions over the next 30% of the animation, and hold steady at their open for the final 20%.

The tick is the simplest of the three animators:


We only animate the trimPathEnd – initially this is held at 0.0 for the first 50% of the animation meaning that none of the tick shows. It them animates to 1.0 over the second 50% of the animation giving the illusion of the tick being drawn.

These are all tied to the components in the Vector drawable:




There is also a complementary animated vector and the constituent animators for each of which handles the transitions from checked to unchecked state.

These are then added to an animated selector to animate the view state changes:




The static drawables used are assigned to the item elements which represent the checked and unchecked states, and then the transitions trigger the relevant animated vector to run when the state changes.

With all of that we get this quite pleasing unchecked to checked (and back again) transition:

Sometimes a little bit of lateral thinking is required to simplify our vectors. In this case the trick of drawing the checked state in an orientation with made the maths much easier, and then rotating it saved us a fair bit of cognitive effort without diminishing the final effect.

The source code for this article is available here.

© 2020, Mark Allison. All rights reserved.

Copyright © 2020 Styling Android. All Rights Reserved.
Information about how to reuse or republish this work may be available at

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.