Android Lollipop introduced a lot of sweet new classes. The one that caught my eye is AnimatedVectorDrawable
, and I decided to check it out right away.
Example from Documentation
The documentation included an example, so I created the files as instructed: res/drawable/vectordrawable.xml
, res/drawable/avd.xml
, res/anim/rotation.xml
and res/anim/path_morph.xml
Now what? There are many ways to use a Drawable
. How about in a TextView
?
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/example_from_documentation" android:drawableBottom="@drawable/avd"/>
No animation yet. Let's start it.
for (Drawable drawable : textView.getCompoundDrawables()) { if (drawable instanceof Animatable) { ((Animatable) drawable).start(); } }
And voilĂ ! Animation. But what is it? Let's step it through.
res/drawable/vectordrawable.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="64dp" android:width="64dp" android:viewportHeight="600" android:viewportWidth="600" > <group android:name="rotationGroup" android:pivotX="300.0" android:pivotY="300.0" android:rotation="45.0" > <path android:name="v" android:fillColor="#000000" android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /> </group> </vector>
This is the VectorDrawable
. The path
defines a triangle, and the group
rotates it by 45 degrees.
res/drawable/avd.xml
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vectordrawable" > <target android:name="rotationGroup" android:animation="@anim/rotation" /> <target android:name="v" android:animation="@anim/path_morph" /> </animated-vector>
Next we have avd.xml
, which rotates the group and morphs the path.
res/anim/rotation.xml
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="6000" android:propertyName="rotation" android:valueFrom="0" android:valueTo="360" />
res/anim/path_morph.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:duration="3000" android:propertyName="pathData" android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z" android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z" android:valueType="pathType"/> </set>
The rotation starts from 0 degrees. But since our drawable is initially rotated at 45 degrees, there is a sudden jump when the animation starts. It takes 6000ms to reach 360 degrees. Meanwhile, the path morphs from a triangle to a rectangle in 3000ms, half the time. So, at 180 degrees, the morph is complete.
Phew, that was not obvious at all. To understand what was happening, I split the rotation and the path morph to observe them separately.
Clock
After trying the example, I wanted to make my own, to see if I can come up with some simple animations that makes sense. I like the idea of animating different parts of the VectorDrawable
, and made a clock.
The hours arm rotates from 9 o'clock to 5 o'clock while the minutes arm goes around from 0 to 60 minutes. The duration of rotations are set differently to give them different speeds.
Smiling face
Next I played with path morph. What is a path morph that makes sense? Let's make a sad face into a happy face!
Points to note
-
The
<vector>
tag must haveandroid:height
andandroid:width
to define the intrinsic width and height of theVectorDrawable
. Your app will crash if you skip them. - If your
VectorDrawable
has a smallerandroid:height
orandroid:width
than when you use them say in anImageView
, your graphic will look pixelated. - To morph from one path to another, the paths must be compatible. They need to have the exact same length of commands, and exact same length of parameters for each command.
I am very excited about VectorDrawable
and AnimatedVectorDrawable
. Scalable graphics FTW!
Source code: https://github.com/chiuki/animated-vector-drawable