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
Inline coding questions will not be answsered. Instead, ask on StackOverflow and put the link in the comment.
I have made online tool for converting SVG into xml resource vector - http://inloop.github.io/svg2android/ - It was not tested so much still in early alpha. It support simple svg files (as android supports), I have tested It with inkscape - drawed some shapes (rect,circle,spiral...), select all then "Path->Object to path", exported into *.svg and dropped into site, generated xml and works fine.
ReplyDeleteYou should definetly promote that tool ... it saved my life :P
DeleteJuraj, your converter kills all animation in SVG file. Perhaps you should add animation support to your tool as well.
Deletegreat tutorial
ReplyDeletenice tutorial, really appreciate your work
ReplyDeleteVery interesting article. VectorDrawables with animations open the gate to a world of endless possibilities. I want to do fancy things with complex vector images.
ReplyDeletethat is superb... but there is this https://github.com/bonnyfone/vectalign which can help with morphing for non-compatible path
ReplyDeletenice work
ReplyDelete