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 have android:height
and android:width
to define the intrinsic width and height of the VectorDrawable
. Your app will crash if you skip them.
- If your
VectorDrawable
has a smaller android:height
or android:width
than when you use them say in an ImageView
, 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