SVG的全称是Scalable Vector Graphics(可缩放矢量图形),它不会因为图像放大而失真,且占用内存小,同时搭配Path动画,能够实现一些意想不到的效果。

Android中的SVG图像又叫Vector图像,它是对原生的SVG进行了简化,利用path来实现绘制。

1、VetcorDrawable

1.1、Vector图形制作

我们可以在svg编辑网页上制作好SVG图像,然后通过Android Studio中的Vector Asset Studio,将SVG转换成Vector。

转换后代码格式大致如下:

android:width="200dp"

android:height="100dp"

android:viewportWidth="100"

android:viewportHeight="50">

android:name="bar"

android:pathData="M50,23 L100,25"

android:strokeWidth="2"

android:strokeColor="@android:color/darker_gray" />

1.2、vector标签属性

标签

含义

width

图形的具体宽度

height

图形的具体高度

viewportWidth

图形横向被划分的个数

viewportHeight

图形纵向被划分的个数

用于vector图形是矢量图,即无限放大也不会失真,所以要指定其宽高。

同时图形中的坐标值,也不能依据宽高的具体值大小,只是就引入了划分比例大小,即viewportXXX。

举例说明:本例中,将大小为200dp x 100dp的图像,划分出100 x 50个小份,每份尺寸为2dp x 2dp;而android:pathData属性中的坐标值,就是相对于这100 x 50个小份所决定的。如坐标(50,50),就对应本图形底部中点。

1.3、path标签属性

1、常用属性

path标签具有以下几个常用属性。

标签

含义

name

声明一个标记,类似于ID,便于对其做动画的时候顺利地找到该节点

strokeWidth

画笔的宽度

fillColor

填充颜色

fillAlpha

填充颜色的透明度

strokeColor

描边颜色

strokeWidth

描边宽度

strokeAlpha

描边透明度

strokeLineJoin

折线拐角形状,取值有miter(结合处为锐角)、round(结合处为圆弧)、bevel(结合处为直线)

strokeLineCap

画出线条的端点的形状(线帽),取值有butt(无线帽)、round(圆形线帽)、square(方形线帽)

strokeMiterLimit

当两条线段以锐角相交的时候,斜面可能很长,视觉上显的不协调。

1、本属性为斜面的长度设置了一个上限,当超出这个上限,它就变成斜角。只在strokeLineJoin为miter时有效。

2、实际上,它表示斜面长度和线条长度的比值,默认值是10,意味着一个斜面的长度不应该超过线条宽度的10 倍。

2、 android:trimPathStart

指定路径的开始位置,取值为0~1。当取值为0时,表示从头部开始;当取值为1时,整条路径不可见。

3、 android:trimPathEnd

指定路径的结束,取值为0~1。当取值为0时,整条路径不可见,当取值为1,整条路径显示完整。当截取的路径超出范围时,会从开始位置继续累计。

4、 android:trimPathOffset

指定结果路径的偏移距离,取值为0~1。当取值为0时,不进行位移,当取值为1,位移整条路径长度。

5、android:pathData

指定图形内容,通过一系列指令和坐标,自动生成对应的图像。

1.4、Vector的常用语法

即Vector中path标签下android:pathData属性里字符串的语法。格式如下:

符号

使用

解释

M = moveto

M X,Y

将画笔移动到指定的坐标位置

L = lineto

L X,Y

画直线到指定的坐标位置

H = horizontal lineto

H V

水平绘制直线到X坐标

V = vertical lineto

V Y

垂直绘制直线到Y坐标

Q = quadratic Belzier curve

Q X,Y,ENDX,ENDY

二次贝塞曲线

T = smooth quadratic Belzier curve

T ENDX,ENDY

二次贝塞曲线

将上一指令的终点作为贝塞尔曲线的起点

C = curveto

C X1,Y1,X2,Y2,ENDX,ENDY

三次贝塞曲线

S = smooth curveto

S X2,Y2,ENDX,ENDY

三次贝塞曲线

将上一指令的终点作为贝塞尔曲线的起点

A = elliptical Arc

A RX,RY,XROTATION,FLAG1,FLAG2,X,Y

弧线

Z = closepath

Z

关闭路径

其中A指令绘制一条弧线,各个参数含义如下:

参数

含义

RX,RY

椭圆的半轴大小

XROTATION

椭圆的X轴和水平方向顺时针方向的夹角

FLAG1

只有两个值,1表示大角度弧度,0表示小角度弧度

FLAG2

只有两个值,确定从起始点到终点的方向,1表示顺时针,О表示逆时针

在使用上面的指令时,需要注意以下几点。

1、坐标轴以(0,0)为中心,X轴水平向右,Y轴水平向下。

2、所有指令大小写均可。大写绝对定位,参照全局坐标系;小写相对定位,参照父容器坐标系。

3、指令和数据间的空格可以省略。

4、同一指令出现多次可以只用一个。

1.5、group标签

group标签主要是将同一个Vector文件中,多个Path组成的图像当做一个整体,便于动画执行。包含以下属性:

标签

含义

name

组的名字,用于与动画相关联

rotation

指定该组图像的旋转度数

pivotX

定义缩放和旋转该组时的X参考点,该值是相对于vector 的 viewport值来指定的

pivotY

定义缩放和旋转该组时的Y参考点,该值是相对于vector 的 viewport值来指定的

scaleX

指定该组X轴缩放大小

scaleY

指定该组Y轴缩放大小

translateX

指定该组沿X轴平移的距离

translateY

指定该组沿Y轴平移的距离

1.6、使用VetcorDrawable

gradle文件中配置:

android {

defaultConfig {

vectorDrawables.useSupportLibrary = true

}

}

ImageView or ImageButton

app:srcCompat="@drawable/vector_image"

Button

通过selector来进行设置,并开启下面的设置

static{

AppCompatDelegate.setCompatVetcorFromResourcesEnabled(true);

}

2、AnimatedVectorDrawable

AnimatedVectorDrawable与VectorDrawable名字上多了一个Animated,这也是它们自己最大的区别,AnimatedVectorDrawable 拥有执行动画的能力。

2.1、AnimatedVectorDrawable使用

1、创建vector图片

android:width="24dp"

android:height="24dp"

android:viewportWidth="24.0"

android:viewportHeight="24.0">

android:fillColor="#8C9EFF"

android:pathData="M9.01,14L2,14v2h7.01v3L13,15l-3.99,-4v3z" />

android:fillColor="#8C9EFF"

android:pathData="M14.99,13v-3L22,10L22,8h-7.01L14.99,5L11,9l3.99,4z" />

2、创建左右动画

左箭头动画

android:duration="1000"

android:interpolator="@android:interpolator/anticipate_overshoot"

android:propertyName="translateX"

android:repeatCount="infinite"

android:repeatMode="reverse"

android:valueFrom="0"

android:valueTo="10"

android:valueType="floatType"/>

右箭头动画

android:duration="1000"

android:interpolator="@android:interpolator/anticipate_overshoot"

android:propertyName="translateX"

android:repeatCount="infinite"

android:repeatMode="reverse"

android:valueFrom="0"

android:valueTo="-10"

android:valueType="floatType"/>

3、配置动画粘合剂

android:drawable="@drawable/ic_vector_arrows">

android:name="left"

android:animation="@animator/vector_left_anim" />

android:name="right"

android:animation="@animator/vector_right_anim" />

4、为ImageView设置appCompat

android:layout_width="100dp"

android:layout_height="100dp"

android:onClick="animatorStart"

app:srcCompat="@drawable/anim" />

5、使用动画

public void animatorStart(View view) {

ImageView imageView = (ImageView) view;

AnimatedVectorDrawable drawable = (AnimatedVectorDrawable)imageView.getDrawable();

drawable.start();

}

我们此时会发现,创建一个Vector动画步骤也太繁琐了吧,没关系,谷歌工程师早就帮我们想好了解决办法,通过合并资源,轻松完成上面前3步。

2.2、轨迹动画

这是一种比较常见的动画,比如以下几种(请原谅我盗图):

451f72f752ee777e3df07be3223b47ea.gif

19101361568977583839781636.gif

看起来是不是很炫酷,其实实现起来很简单:

将objectAnimator动画文件android:valueType属性设置为floatType,android:propertyName属性设置为trimPathStart,trimPathEnd,trimPathOffset之一,并指定android:valueTo和android:valueTo。

当动画执行后,会不断修改上述3个属性的值,以实现各种轨迹动画效果。这3个属性含义上文已经解释,这里就不再提及。

知道了上面的内容,就能很好理解属性动画的定义产生的不同效果了:

1、使用trimPathStart属性,valueFrom:0,valueTo:1

线条从起点缩短到终点,即初始截断部分是0%,从起点开始逐渐扩大到终点,达到100%。

2、使用trimPathStart属性,valueFrom:1,valueTo:0

线条从终点增长到起点,即初始截断部分是100%,从终点开始逐渐缩小到起点,达到0%。

3、使用trimPathEnd属性,valueFrom:0,valueTo:1

线条从起点增长到终点,即初始截断部分是100%,从起点开始逐渐缩小到终点,达到0%。

4、使用trimPathEnd属性,valueFrom:1,valueTo:0

线条从终点缩短到起点,即初始截断部分是0%,从终点开始逐渐扩大到起点,达到100%。

2.3、路径动画

路径动画,相对来说就麻烦一下,但麻烦的在于制作,不是使用,使用时,只需将propertyName设置为pathData,valueType设置为pathType即可。Android就可以从一种图像变成另一种图像。

3、兼容性

3.1、VectorDrawable

Android L,只兼容minSDK>=21的版本

Gradle Plugin 1.5

设备版本>=21——使用Vector

设备版本<21——将Vector转换为png

AppCompat23.2后,VectorDrawable几乎可以兼容大部分使用场景

静态Vector支持Android2.1+

动态Vector支持Android3.0+

3.1、AnimatedVectorDrawable兼容性

1、向下兼容问题

Path Morphing

路径变换动画,在Android pre-L版本下是无法使用的

Path Interpolation

路径插值器,在Android pre-L版本下只能使用系统的插值器,不能自定义

2、向上兼容问题

Path Morphing

路径变换动画,在Android L版本以上需要使用代码配置