一、背景
由于android 碎片化严重,对于不同型号手机、不同屏幕分辨率的适配,就显得异常艰难了。一般的做法是切好几套分辨率的图来保证拉伸不会出现太大的问题,虽说多几套图可以基本解决适配的问题,但是会造成安装包的体积增大,同时一些不常见的设备上也容易出现变形的问题,Android Vector 的出现可以解决此问题。
二、什么是svg
- SVG 意为可缩放矢量图形(Scalable Vector Graphics)
- SVG 使用 XML 格式定义图形,运行的时候才会去通过一些特定的语法和规则渲染绘制出图像
- 图像在放大或改变尺寸的情况下其图形质量不会有所损失
- SVG 是万维网联盟的标准,与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体,用来定义用于网络的基于矢量的图形
- 可以直接用 编写 XML 来描绘图片,使图片具有很强的交互性
注:svg目前在网页端被广泛的使用,android 中是通过什么来实现的呢 ?google 提供了VectorDrawable和AnimatedVectorDrawable两个类来实现svg ,也即是Vector 就是SVG 在android 中的实现,从android 5.0开始支持,google也从AppCompat23.2 版本提供了对低版本svg 的兼容。
svg更详细的介绍和用法请参照w3 School连接,请点我
Android vector 更细的介绍和用法请参照google网站api 请点我
三、矢量图和位图
位图:是由像素点组合而成的图像,一个点就是一个像素,每个点都有自己的颜色。位图和分辨率有着直接的联系,分辨率大的位图清晰度高,其放大倍数也相应增加。但是,当位图的放大倍数超过其最佳分辨率时,就会出现细节丢失,并产生锯齿状边缘的情况。像平时移动端用的比较多的png格式的图片就是位图
矢量图:是以数学向量方式记录图像的,其内容以线条和色块为主。矢量图和分辨率无关,它可以任意地放大且清晰度不变,也不会出现锯齿状边缘,本文要讲的svg就是矢量图
四、Android 使用svg 的优势和劣势
- 优势
- SVG 可被非常多的工具读取和修改(比如记事本)
- SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强。
- SVG 是可伸缩的
- SVG 图像可在任何的分辨率下被高质量地打印
- SVG 可在图像质量不下降的情况下被放大
- SVG 图像中的文本是可选的,同时也是可搜索的(很适合制作地图)
- SVG 可以与 Java 技术一起运行
- SVG 是开放的标准
- SVG 文件是纯粹的 XML
- 它最主要优点就是不会降低图片质量的前提下,可以适应所有分辨率屏幕
- 方便实现很多优美的动画效果
- 劣势:
- Vector是Android 5.0 之后才出来的,从 AppCompat23.2 开始支持5.0版本以下使用Vector。部分设备兼容有问题
- Android Vector Drawable 并不支持所有 SVG 的语法,例如需要将网页中的svg图片转化到Android Vector时,不成功,此时需要修改部分属性才可使用,但支持的语法已经足够使用。
- 运行时才绘制,效率不高
五、如何使用
1、语法
VectorDrawable 使用 <vector>元素在XML 中定义,代码如下
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="64dp"
android:width="64dp"
android:viewportHeight="600"
android:viewportWidth="600" >
<group
android:name="rotationGroup"
android:pivotX="300.0"
android:pivotY="300.0"
android:rotation="45.0" >
<path
android:name="v"
android:fillColor="#000000"
android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
</group>
</vector>
Vector属性
-
<vector> 用于定义一个可绘制的矢量图
- android:name 矢量图的名称
- android:width 用于定义drawable的内在宽度。这支持所有尺寸单位,通常用dp指定
- android:height 用于定义drawable的内在高度。这支持所有尺寸单位,通常用dp指定
- android:viewportWidth 用于定义视图空间的宽度,即虚拟画布的宽度
- android:viewportHeight于定义视图空间的高度,即虚拟画布的高度
- android:tint 作为色彩应用于绘图的颜色,默认不着色
- android:tintMode Porter-Duff混合模式用于色调颜色。默认是src_in。
- android:autoMirrored 指示绘图窗口的布局方向为RTL(从右到左)时是否需要镜像。默认为false。
- android:alpha drawable的不透明度。默认值是1.0。
group
- **<group> 定义一组路径或子组,以及转换信息。用于缩放、旋转、位移
- android:name 组名称
- android:rotation 组的旋转角度,默认为0
- android:pivotX 组的缩放和旋转的枢轴的X坐标,默认为0
- android:pivotY 组的缩放和旋转的枢轴的Y坐标,默认为0
- android:scaleX X坐标上的缩放量,默认为1
- android:scaleY Y坐标上的缩放量,默认为1
- android:translateX X坐标上的平移量,默认为0
- android:translateY Y坐标上的平移量,默认为0
Path
-
<path> 定义绘制的路径
- android:name ,路径名称
-
android:pathData ,路径
- 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(X2, Y2, X ,Y) ,光滑三次贝塞尔曲线
- Q = quadratic Belzier curve (Q X,Y,ENDX,ENDY),二次贝赛曲线
- T = smooth quadratic Belzier curveto (T ENDX,ENDY) ,映射
- A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y) ,弧线
- Z = closepath (Z) ,关闭路径
注释:以上所有命令均允许小写字母。大写表示绝对定位,小写表示相对定位。
- android:fillColor 指定用于填充路径的颜色。可以是颜色,或者对于SDK 24+,可以是颜色状态列表或渐变颜色(请参阅GradientColor 和 GradientColorItem)。如果此属性为动画,则由动画设置的任何值都将覆盖原始值。如果未指定此属性,则不绘制路径填充。
- android:strokeColor 指定用于绘制路径轮廓的颜色。可以是颜色,或者对于SDK 24+,可以是颜色状态列表或渐变颜色(请参阅GradientColor和GradientColorItem)。如果此属性为动画,则由动画设置的任何值都将覆盖原始值。如果未指定此属性,则不绘制路径轮廓。
- android:strokeWidth 路径行程的宽度。缺省值是0
- android:strokeAlpha 路径笔画的不透明度。缺省值是1。
- android:fillAlpha 不透明度填补路径。缺省值是1。
- android:trimPathStart 要从头开始修剪的路径的分数,范围从0到1.默认值为0。
- android:trimPathEnd 从末尾修剪的路径的分数,范围从0到1.默认值为1。
- android:trimPathOffset 移位修剪区域(允许显示的区域包括开始和结束),范围从0到1.默认值为0。
- android:strokeLineCap 设置描边路径的线条:对接,圆形,方形。默认是对接。
- android:strokeLineJoin 设置描边路径的lineJoin:斜角,圆形,斜角。缺省是斜角。
- android:strokeMiterLimit 设置描边路径的斜接限制。缺省值是4
clip-path
-
<clip-path> 定义路径为当前剪辑。请注意,剪辑路径仅适用于当前组及其子组。
- android:name定义剪辑路径的名称
- android:pathData 使用与SVG路径数据中 path数据来定义
2、简单实例:
这里我们以网页 使用的svg图片来生成android 中的svg图片来说明,为什么不直接使用VectorDrawable 的元素及其属性来生成svg呢?
因为我们要使用上述讲解的各个元素及属性生成,是极其复杂的,作为程序员不应该把时间学浪费到上面,只需看懂即可
我们可以通过svg编辑软件生成svg图片,或者UI提供好的svg 图片转化为android 可以使用的格式,即在已有资源的基础上进行改进,效率会更高
1.将下面xml 代码用.svg的文件保存,命名为test.svg
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" stroke="black"
stroke-width="2" fill="red"/>
</svg>
2.用支持svg的浏览器打开(如chrome)
3.转化为android 中可以使用的xml,这里使用到了android studio 中的Vector Asset ,如下图:
4.选择Local file(SVG,PSD),设置本地路径,修改文件名、大小等即可将上述网页中使用的svg,转化为android 中使用的svg 图片
5.转化后的svg代码如下:
<vector android:height="24dp" android:viewportHeight="100.0"
android:viewportWidth="100.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#ff0000"
android:pathData="M50,50m-40,0a40,40 0,1 1,80 0a40,40 0,1 1,-80 0"
android:strokeColor="#000000" android:strokeWidth="2"/>
</vector>
- 布局文件和代码中使用vector 图片
-
布置文件
代码中
ImageView iv = findViewById(R.id.iv);
iv.setImageResource(R.drawable.ic_test);
可以看出和位图 png 格式的图片使用基本一致~
3.动画
动画施工ing
六、结语
Vector的出现对开发者来说是一大福音,可能在某些低版本还是会存在兼容性问题,但我们可以尝试在一些不太重要的功能上先使用,积累经验,当某一天,我们不需要考虑低版本系统,或者低版本的兼容库已经做的非常强大的时候,或许svg 会替代目前使用的位图(png)也说不一定。