SVG学习--VectorDrawable的使用

来源:互联网 发布:金达莱花dj网络歌手 编辑:程序博客网 时间:2024/05/22 02:04

作者:r17171709
原文地址:http://www.jianshu.com/p/709994b08683

SVG的全称是Scalable Vector Graphics,叫可缩放矢量图形。它和位图(Bitmap)相对,SVG不会像位图一样因为缩放而让图片质量下降。它的优点在于节约空间,使用方便。
Android 5.0中引入了 VectorDrawable 来支持矢量图(SVG),同时还引入了 AnimatedVectorDrawable 来支持矢量图动画,在最近几次Support包更新之后,SVG的兼容性问题得以大大改善
基于以上所述,是时候了解一下SVG的实现了

SVG图片的加载

AS本身就支持SVG的加载,右击drawable,通过Vector Asset直接加载一个SVG图像

打开SVG选择

这里写图片描述

选择一张AS自带的SVG图片

这里写图片描述

<vector xmlns:android="http://schemas.android.com/apk/res/android"        android:width="24dp"        android:height="24dp"        android:viewportWidth="24.0"        android:viewportHeight="24.0">    <path        android:fillColor="#FF000000"        android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></vector>

初步解释一下标签的含义
android:width/android:height: 这个无需多说,这个是整个图片的宽高
android:viewportWidth/android:viewportHeight: 画布大小。这个值最好与android:width/android:height保持一致,因为android:pathData使用的坐标系范围与他相关。在宽高不会改变的情况下,改变SVG自身内部坐标系的大小,造成图片的偏移与缩放
android:fillColor: SVG路径的填充色
android:pathData: SVG路径

乍一看这个路径描述的内容我们看的一头雾水,我们一步一步来,学习完基本概念,就能很轻松的理解了

pathData命令

pathData命令一般由字母跟数字组成,字母多为命令关键字(这里有个大小写的区别,大写的字母是基于原点坐标系的偏移量,即绝对位置;小写字母是基于当前点坐标系的偏移量,即相对位置),数字多为坐标,

M(x y): 没什么好说的,移动画笔到指定点,并不进行绘制,默认在(0,0)点。与Paint里面moveTo可以理解成一样的概念

L(l) (x y) : 就是直接画一条线了,与它类似的有H(h)跟V(v)。这里有一个方向的概念,pathData中的方向与View绘制的方向是一样的。H就是画一条横线,V就是画一条竖线,L就是画点到点之间的线

Z: 没有参数,就是连接起点跟终点

A(rx ry x-axis-rotation large-arc-flag sweep-flag x y): 绘制圆弧。里面的参数比较多,
rx\ry 是椭圆在X\Y轴的半径
x-axis-rotation 是X轴旋转角度
large-arc-flag 0表示取小弧度,1表示取大弧度(这个通过下图可以理解)
sweep-flag 0表示逆时针方向,1表示顺时针方向

这里写图片描述

我们继续上一张图看看

<vector xmlns:android="http://schemas.android.com/apk/res/android"    android:width="24dp"    android:height="24dp"    android:viewportWidth="24.0"    android:viewportHeight="24.0">    <path        android:fillColor="@color/colorPrimary"        android:pathData="M12,12 a4,6 0 1 1 3,4"/>    <path        android:fillColor="@android:color/holo_green_light"        android:pathData="M12,12 a4,6 0 0 1 3,4"/>    <path        android:fillColor="@android:color/holo_purple"        android:pathData="M12,12 a4,6 0 1 0 3,4"/>    <path        android:fillColor="@android:color/holo_orange_light"        android:pathData="M12,12 a4,6 0 0 0 3,4"/></vector>

这里绘制了半径为4dp、6dp的椭圆,椭圆上有2点(12,12)与(15,16),按照大圆弧小圆弧顺逆时针方向4种状态

这里写图片描述

Q(x1 y1 x y): 二次贝塞尔曲线。在之前的文章里面,我已经说过贝塞尔曲线的概念,如果还不是很了解,请参阅利用属性动画,实现简单的爱心气泡点赞效果一文所涉及到的相关知识。这里(x1, y1)是控制点的坐标,(x,y)是终点坐标。还有一个类似的T指令,他只有终点参数可以设置,他的控制点被默认为上一次的控制点关于上次终点的中心对称点,比如上一次的控制点P1是(6,6),终点P2是(8,10), 那么使用T指令后默认控制点P1`为(10,14)。

<path android:strokeColor="@android:color/holo_red_dark"    android:strokeWidth="0.1"    android:pathData="M12,12 Q 14,14 18,13"></path>

这里写图片描述

C(x1 y1 x2 y2 x y): 三次贝塞尔曲线。同二阶一样,前2个坐标为2个控制点的坐标,最后一个为终点坐标。这里还有一个S指令,同T指令功能相同,就是上一次最后一个控制点相对上次的终点的中心对称点

<path android:strokeColor="@android:color/holo_red_dark"    android:strokeWidth="0.1"    android:pathData="M12,12 C 14,14 18,13 20,8"></path>

这里写图片描述

至此,我们就把SVG涉及到画图的部分学习完了,我们再回过头来看看刚才的drawable是怎么实现的

+号的实现

同样是一笔一笔的用L\H\V组合而成

投机取巧

给大家一个网址阿里巴巴矢量图标库,这个里面可以下载好web版本的SVG图片,然后我们将其拷贝到Android SVG to VectorDrawable,这样我们就能大致获取到各种素材的SVG图片了

注意事项

以上写法在android 5以上是没有任何问题的,但是放到之前版本上就会出现问题,看看之前的圆弧

Paste_Image.png

原本是彩色的,在这里变成黑色的了。。。怎么办?

1 在build.gradle里面进行配置

android {    defaultConfig {        vectorDrawables.useSupportLibrary = true    }}

2 只能用于AppCompatImageView或者AppCompatImageButton或其子类,而且必须在app:srcCompat标签中使用。

这样是肯定没有问题的,但是问题在于,我不可能把代码里面所有View都改成这2种。。。

3 SVG图像需要依附于StateListDrawable,InsetDrawable,LayerDrawable,LevelListDrawable,RotateDrawable,这样就可以在低版本中显示了。StateListDrawable最简单,就是直接写一个selector即可

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@drawable/ic_a"></item></selector>

别忘记还有一个标志位要开启,在activity的最上方

static {    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);}

这样就没问题了

4 换色
如果你想手动更换图片的背景色,那么只要这样就可以了

VectorDrawableCompat a=VectorDrawableCompat.create(getResources(), R.drawable.ic_a, getTheme());a.setTint(Color.RED);ImageView imageview= (ImageView) findViewById(R.id.imageview);imageview.setImageDrawable(a);

Paste_Image.png

如何手动更换某一部分Path的色值,我暂时还不知道,如果你知道,请告诉我

参考文章

Android vector 标签 pathData 详解
关于android中矢量图如何用,有坑,爬坑,如何替代的另一些看法

原创粉丝点击