SVG的全称是Scalable Vector Graphics(可缩放矢量图形),它不会因为图像放大而失真,且占用内存小,同时搭配Path动画,能够实现一些意想不到的效果。
Android中的SVG图像又叫Vector图像,它是对原生的SVG进行了简化,利用path来实现绘制。
1、VetcorDrawable
1.1、Vector图形制作
我们可以在svg编辑网页上制作好SVG图像,然后通过Android Studio中的Vector Asset Studio,将SVG转换成Vector。
转换后代码格式大致如下:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="100dp"
android:viewportWidth="100"
android:viewportHeight="50">
<path
android:name="bar"
android:pathData="M50,23 L100,25"
android:strokeWidth="2"
android:strokeColor="@android:color/darker_gray" />
</vector>
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图片
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<group android:name="left">
<path
android:fillColor="#8C9EFF"
android:pathData="M9.01,14L2,14v2h7.01v3L13,15l-3.99,-4v3z" />
</group>
<group android:name="right">
<path
android:fillColor="#8C9EFF"
android:pathData="M14.99,13v-3L22,10L22,8h-7.01L14.99,5L11,9l3.99,4z" />
</group>
</vector>
2、创建左右动画
左箭头动画
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
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"/>
右箭头动画
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
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、配置动画粘合剂
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_vector_arrows">
<target
android:name="left"
android:animation="@animator/vector_left_anim" />
<target
android:name="right"
android:animation="@animator/vector_right_anim" />
</animated-vector>
4、为ImageView设置appCompat
<ImageView
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、轨迹动画
这是一种比较常见的动画,比如以下几种(请原谅我盗图):
看起来是不是很炫酷,其实实现起来很简单:
将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版本以上需要使用代码配置