下面使用SVG标记定义一个心形,先上个心形的效果图:
心形对应的矢量图形定义示例如下:<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="256dp" android:height="256dp" android:viewportHeight="32" android:viewportWidth="32"> <path android:fillColor= "#ffaaaa" android:pathData= "M20.5,9.5 c-1.955,0,-3.83,1.268,-4.5,3 c-0.67,-1.732,-2.547,-3,-4.5,-3 C8.957,9.5,7,11.432,7,14 c0,3.53,3.793,6.257,9,11.5 c5.207,-5.242,9,-7.97,9,-11.5 C25,11.432,23.043,9.5,20.5,9.5z" /></vector>矢量动画AnimatedVectorDrawable
费了老大的劲搞清楚SVG标记,如果仅仅画个静态的矢量图形,未免大材小用了。其实矢量图形真正的意义在于矢量动画,通过动态计算几何路径的坐标,从而实现局部或整体的动画效果,这才是矢量图形的杀手锏呀。Android提供了AnimatedVectorDrawable这么一个矢量动画类,但开发者还得通过属性动画及其xml标签方可实现动画定义。先看看AnimatedVectorDrawable的几个常用方法:registerAnimationCallback : 注册动画监听器,需实现Animatable2.AnimationCallback接口的两个方法:onAnimationStart和onAnimationEnd。start : 开始播放动画。stop : 停止播放。reverse : 倒过来播放。再看看如何通过属性动画实现矢量动画效果。理论上,矢量图形的三个标签(vector、group、path)都有可以用来播放动画的属性;不过实际开发的时候,常用的只有三类属性可用作动画,说明如下:变换类属性
这类属性包括vector标签的android:alpha,以及group标签的android:rotation、android:scaleX、android:scaleY、android:translateX、android:translateY等等,这几个属性分别对应于补间动画的灰度动画、旋转动画、缩放动画、平移动画。因为该类属性实现的是大家熟悉的补间动画效果,所以这里就不再做演示了。路径类属性
这类属性主要指path标签的android:pathData,通过设置几何路径的起始状态与终止状态,可实现两个几何形状之间的渐变效果,如一个圆圈从小变大,又如一条曲线变成直线等等。下面是个从哭丧脸变为笑脸的动画截图:下面是人脸的矢量图形定义文件vector_face_eye.xml:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="200dp" android:width="200dp" android:viewportHeight="100" android:viewportWidth="100" > <path android:fillColor="@color/yellow" android:pathData="@string/path_circle"/> <path android:name="eye_left" android:strokeColor="@android:color/black" android:strokeWidth="4" android:strokeLineCap="round" android:pathData="@string/path_eye_left_sad"/> <path android:name="eye_right" android:strokeColor="@android:color/black" android:strokeWidth="4" android:strokeLineCap="round" android:pathData="@string/path_eye_right_sad"/> <path android:name="mouth" android:strokeColor="@android:color/black" android:strokeWidth="4" android:strokeLineCap="round" android:pathData="@string/path_face_mouth_sad"/></vector>接着是脸部三处器官变化的属性动画定义文件。下面是左眼的属性动画定义文件anim_smile_eye_left.xml:<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="3000" android:PRopertyName="pathData" android:valueFrom="@string/path_eye_left_sad" android:valueTo="@string/path_eye_left_happy" android:valueType="pathType" android:interpolator="@android:anim/accelerate_interpolator"/>下面是右眼的属性动画定义文件anim_smile_eye_right.xml:<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="3000" android:propertyName="pathData" android:valueFrom="@string/path_eye_right_sad" android:valueTo="@string/path_eye_right_happy" android:valueType="pathType" android:interpolator="@android:anim/accelerate_interpolator"/>下面是嘴巴的属性动画定义文件anim_smile_mouth.xml:<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="3000" android:propertyName="pathData" android:valueFrom="@string/path_face_mouth_sad" android:valueTo="@string/path_face_mouth_happy" android:valueType="pathType" android:interpolator="@android:anim/accelerate_interpolator"/>最后是笑脸的矢量动画定义例子animated_vector_smile_eye.xml:<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vector_face_eye" > <target android:name="mouth" android:animation="@anim/anim_smile_mouth" /> <target android:name="eye_left" android:animation="@anim/anim_smile_eye_left" /> <target android:name="eye_right" android:animation="@anim/anim_smile_eye_right" /> </animated-vector>不要忘了在代码中进行矢量动画的播放操作:private void startVectorSmile() { iv_vector_smile.setImageResource(R.drawable.animated_vector_smile_eye); Drawable drawable = iv_vector_smile.getDrawable(); if (drawable instanceof AnimatedVectorDrawable) { ((AnimatedVectorDrawable) drawable).start(); } }修剪类属性
这类属性包括path标签的android:trimPathStart和android:trimPathEnd,可实现矢量图形逐步展开或者逐步消失的动画效果。下面是个支付宝支付成功的动画截图:支付成功动画包含两个形状,首先在外面画个圆圈,然后在圆圈里面画个打勾符号。因为圆圈和打勾并不相连,如果按照一般的处理,就会一边画圆圈一边画打勾,这不是我们所希望的画完圆圈再画打勾的效果。所以要想让圆圈动画和打勾动画按顺序播放,得分别定义圆圈的矢量图形和打勾的矢量图形,然后等圆圈动画播放完毕,再开始播放打勾动画。下面是圆圈的矢量图形定义文件vector_pay_circle.xml:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="100dp" android:viewportHeight="100" android:viewportWidth="100" android:width="100dp" > <path android:name="circle" android:pathData=" M 10,50 A 40 40 0 1 0 10 49" android:strokeAlpha="1" android:strokeColor="@color/blue_sky" android:strokeLineCap="round" android:strokeWidth="3" /></vector>下面是打勾的矢量图形(含圆圈图形)定义文件vector_pay_success.xml:<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="100dp" android:viewportHeight="100" android:viewportWidth="100" android:width="100dp" > <path android:name="circle" android:pathData=" M 10,50 A 40 40 0 1 0 10 49" android:strokeAlpha="1" android:strokeColor="@color/blue_sky" android:strokeLineCap="round" android:strokeWidth="3" /> <path android:name="hook" android:pathData=" M 30,50 L 45 65 L 75 35" android:strokeAlpha="1" android:strokeColor="@color/blue_sky" android:strokeLineCap="butt" android:strokeWidth="3" /></vector>接着是支付成功的属性动画的xml定义文件anim_pay.xml:<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:interpolator="@android:interpolator/linear" android:propertyName="trimPathEnd" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" />最后是矢量动画的定义文件,下面这个用来播放圆圈动画:<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vector_pay_circle"> <target android:name="circle" android:animation="@anim/anim_pay" /></animated-vector>下面这个用来播放圆圈动画后继的打勾动画:<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vector_pay_success"> <target android:name="hook" android:animation="@anim/anim_pay" /></animated-vector>圆圈动画播放完毕,接着播放打勾动画,这要在代码中控制,具体的是调用AnimatedVectorDrawable对象的registerAnimationCallback方法,一旦监听到原动画播放结束,然后开始播放新动画。点击下载本文用到的矢量图形与矢量动画的工程代码点此查看Android开发笔记的完整目录
新闻热点
疑难解答