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版本以上需要使用代码配置