在Android5.0(API Level 21)中开始支持SVG的绘制,SVG有以下几个特点:
- 可伸缩的矢量图形(Scalable Vector Graphics)
- 使用XML格式定义图形
- 图形在放大或改变尺寸时,图像不会失真
- 基于W3C标准,与Web中的矢量图通用
Android中可以使用<path>标签绘制SVG,相比Bitmap,SVG最大的优点是缩放不会失真,这样不需要为不同的分辨率设计多套图标,从而缩小APK的体积。
path标签和SVG指令
使用<path>标签创建SVG,类似于用指令的方式控制一只画笔绘制图像。<path>标签支持的SVG指令有:
- M = moveto(M X,Y):将画笔移动到指定的坐标位置,但未发生绘制
- L = lineto(L X,Y):画直线到指定的坐标位置
- H = horizontal lineto(H X):画水平线到指定的X坐标位置
- V = vertical lineto(V Y):画垂直线到指定的Y坐标位置
- C = curveto(C X1,Y1,X2,Y2,ENDX,ENDY):三次贝塞尔曲线
- S = smooth curveto(S X2,Y2,ENDX,ENDY):三次贝塞尔曲线,一般跟在C或S命令后面
- Q = quadratic curveto(Q X,Y,ENDX,ENDY):二次贝塞尔曲线
- T = smooth quadratic curveto(T ENDX,ENDY):二次贝塞尔曲线,一般跟在Q或T命令后面
- A = elliptical arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧线
- Z = closepath():关闭路径
使用以上指令时,需要注意:
- 坐标轴为以(0,0)为中心,X轴水平向右,Y轴水平向下。
- 所有指令大小写均可。大写绝对定位,参照全局坐标系;小写相对定位,参照父容器坐标系。
- 指令和数据间的空格可以省略。
- 同一指令连续出现多次可以只声明一次。
指令的详细解释可以参考MDN文档。
SVG指令的写法固定,并且比较复杂,一般可以通过SVG编辑器来绘制SVG图像,然后将其转换为SVG代码。常用的SVG编辑器有在线的Method Draw和离线的Inkscape。
SVG绘制
在Android中,可以使用VectorDrawable创建基于XML的SVG。在XML中创建SVG时,path标签是SVG的最小单位,而group标签将不同的path标签进行组合,最终形成一棵SVG树。
下面是一个“心形”矢量图的例子:
1 | <?xml version="1.0" encoding="utf-8"?> |
矢量动画
在Android中,可以使用AnimatedVectorDrawable实现矢量动画。AnimatedVectorDrawable的主要功能是将静态的VectorDrawable和动态的ObjectAnimator连接起来,产生动画效果。因此,矢量动画最终还是通过属性动画实现的。
使用矢量动画一般有以下几个步骤:
- 在res/drawable/路径下利用vector标签定义要进行动画的矢量图
- 在res/drawable/路径下利用animated-vector标签定义矢量动画
- 在res/anim/路径下利用objectAnimator标签定义矢量动画使用的属性动画
矢量图中能够产生动画效果的元素是path和group元素,在定义矢量动画时,需要进行动画的元素必须要定义唯一的android:name属性。
矢量动画的具体示例如下:
定义矢量图:
1 | <!-- res/drawable/vectordrawable.xml --> |
根据name属性定义矢量动画:
1 | <!-- res/drawable/animvectordrawable.xml --> |
定义矢量动画对应的属性动画:
1 | <!-- res/animator/rotation.xml --> |
1 | <!-- res/animator/path_morph.xml --> |
需要注意的是,对pathData属性进行动画时,valueTo和valueFrom值必须要兼容,即要有同样数量的命令,并且命令的参数数量要相同。