There is a nice micro-animation library at useanimations.com 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 first animated icon that we’ll look at is one named Loading V2. It consists of a grid of 4×4 boxes which grow and fade is a wave which flows across the icon diagonally. This can be seen towards the bottom of the useanimations.com page in the Loading
section. It is a looping animation a little like a circular indeterminate ProgressBar
which will repeat until it is stopped.
The first thing that we need to do is create a static Vector Drawable resource which represents the 16 boxes which comprise the 4×4 grid:
. . .
This is actually quite repetitive, so I have only displayed the first two boxes. The thing to note is that they are identical aside from the group name, and translateX
and translateY
attributes. The pathData
of each of the boxes is identical and uses a string resource which is defined as M0,0h12v12h-12z
. This draws a 12×12 pixel square.
The pivotX
and pivotY
attributes specify the point around which we’ll scale each box – which is its centre point; and the scaleX
and scaleY
attributes set the default state – which is fully collapsed. All of the boxes start collapsed, and we’ll grow them to full size and then shrink them back again during the animation.
It’s worth mentioning that the vector itself is actually drawn completely white, but in the layouts I use a tint
value to apply colouring to it. This is a useful trick with vectors because it enables them to follow the app theme much easier than hardcoding colour values within the vector asset itself.
The animator to grow and shrink the box in position 1,1 (the top left box) looks like this:
This is an ObjectAnimator
which defines the duration of the animation, and the fact that it will repeat indefinitely. The sample project is minSdkVersion="23"
which means that I am able to use <propertyValuesHolder>
and <keyframe>
which were both introduced in API 23. It is certainly possible to create this animation without them, and you’ll need to do that in order to support earlier API levels, but they make the code a lot more compact and easier to understand which is why I have elected to use them here.
<propertyValuesHolder>
specifies the attribute whose value will be animated. In this case we are animating the scaleX
and scaleY
attributes of the group
in the static vector that we looked at earlier. The <keyframe>
s control how the value will change over the course of the animation. The fraction
attributes are all in the range 0.0-1.0
where 0.0
is the start of the animation and 1.0
is the end. The value
attribute control what the value of the property will be at that point of the animation. The animator will interpolate the values between these key frames.
So with the values shown above: For the first 20% of the animation (from 0.0-0.2
the value will go from 0.0-1.0
; then it will hold at 1.0
for the next 30% (from 0.2-0.5
); then it will change from, 1.0-0.0
over the next 20% (from 0.5-0.7
); and then it will hold at 0.0
for the remaining 30% (from 0.7-1.0
). This will grow the box, hold it at full size, then shrink it back again when applied to the scaleX
and scaleY
attributes as we are here.
This gets attached to the vector in the animated-vector:
. . .
This links the objectAnimator
that we just looked at to the group named 1-1
in the vector that we looked at earlier.
So that will animate one of the boxes, so now we need to apply the same to the other boxes, but stagger them to create the wave effect. If you look at the animation at the beginning of this article, the wave actually flows with the diagonals that run bottom left to upper right. The first cell to move is the top left at 1,1
, followed by the two cells immediately to the right and below it at 2,1
, and 1,2
which move together. The next block to move is the three cells at 3,1
, 2,2
, and 1,3
, and so on. In all there are seven separate phases. Let’s take a look at the animator that we use for the second phase (calls 2,1
and 1,2
):
This is actually identical to the previous animator except that we use different fraction values for each of the key frames. This runs an identical animation sequence, but it is offset so that everything happens 5% of the total duration after the first phase animation.
We can now add this to both the cells in the second phase:
. . .
We do the same for the remaining phases offsetting each phase by another 5%, and this will build up the entire animation. I won’t bother including all of this here, but you can see it in the accompanying source code.
While this does not perfectly match the timing of the phases in the original animation that I’m basing it upon, this demonstrates the basic technique at work here. To mimic the original animation more precisely would mean studying the timing of it, and then adjusting the key frame values to match the original. However, I’m fairly happy with how this animation feels, so we’ll leave it there.
The source code for this article is available here.
© 2019, Mark Allison. All rights reserved.
Copyright © 2019 Styling Android. All Rights Reserved.
Information about how to reuse or republish this work may be available at http://blog.stylingandroid.com/license-information.