SVG

SVG

1、什么是 SVG ?  
        SVG是指可伸缩矢量图形 (Scalable Vector Graphics),它不同于传统的位图,不是通过存储图像中每一点的像素值来保存与使用图形,而是通过 XML 文件来定义一个图形,通过一些特定的语法和规则来绘制出我们所需的图像——同样是使用一张图片,SVG 的方式是事先定义好怎么去画这个图,然后等要用的时候再把它去画出来,而使用传统的位图的话就是已经有了画出来的图,然后要用的时候直接把画好的图拿出来用。这样一来的话我们就很容易可以分析出它们两种方式之间的优劣之处:
   SVG 是在要用图的时候再把图画出来,所以理所当然的在图片显示的时候会花费更多的时间消耗更多的资源。 
   同样由于上一个原因, SVG 并不太适合层次过于复杂细节过于繁多的图片。 
   位图是事先已经画好的图片,所以适应性必然没有 SVG 好,同一张图片在不同分辨率下显示会有差异。 
  SVG 的文件里存储了绘制图片的相关信息,所以我们能够对图片的线条有一个非常清晰的感知,这在做动画的时候特别有用。 
  SVG 没有存储任何图像的像素信息,所以 SVG 的文件体积远小于传统的位图文件。 
  SVG 的文件画出来的图像是矢量图,所以不会存在失真的问题,理论上支持任何级别的缩放。 
从上面的分析大家可以发现,在 SVG 的众多优点下, 它的缺点几乎可以忽略不计了(当然,前提是它所耗费的资源不会对用户体验造成较大的影响

2、SVG in Android
       既然 SVG 这么好,那么为什么当前并没有多少 Android 应用是使用了 SVG 图片的呢?因为市场。Android对于 SVG 的支持是从 Android L 开始的,它的 SDK 里面加入了 VectorDrawable , AnimatedVectorDrawable 等类帮助我们构建 SVG 图形以及动画,并且你可以在 xml 文件里面直接使用 <vector/> 标签绘制 SVG 图像以及 <animated-vector/> 标签为 SVG 图像分配动画。
      但是请注意,目前并没有官方的 support 包来帮助我们对运行着 Android L 之前的系统的设备做兼容,而在一些开源社区里一些人做的兼容包也都还没有那种比较完美的解决方案,总是会有一些问题——这意味着,如果不想将就的话,就只能等到市场上基本都是 Android L 或以上的设备的时候,才有可能在生产中大规模的全面的用 SVG 替换位图了。而目前,2016年秋,据友盟统计,Android L 及以上的设备的市场占有率仅有 43.27% ,一半都不到——但是很显然,距离 SVG 在 Android 上发力的时候没有多远了,毕竟目前在售卖的 Android 手机已经基本上都是搭载的 Android L 及以上的系统了,只待老设备被淘汰。

3、SVG 的使用
3.1,获得一个 SVG 文件
       要使用 SVG ,那么首先我们肯定得有一个 SVG 文件。我们一般都有两种方式来获得一个 SVG 文件:自己写一个 SVG 文件,或者通过 AI 或一些网站作图之后导出它的 SVG 文件。

3.1.1,自己写一个 SVG 文件(Android 中)
      前面说过,SVG 文件里面存储的是如何去绘制目标图片的相关信息,所以理论上我们是可以从 0 开始写一个我们自己的 SVG 文件的——只要知道它绘制文件的规则,一切皆可绘制。我们先来看一下一个简单的 SVG 文件:
    
    
  1. <vector xmlns:android="http://schemas.android.com/apk/res/android"
  2.        android:width="132dp"
  3.        android:height="132dp"
  4.        android:viewportHeight="132.0"
  5.        android:viewportWidth="132.0">
  6.    <path
  7.        android:pathData="M50,2 L80.813,2 L80.813,130 L50,130 L50,2 Z"
  8.        android:strokeColor="#e33e2b"
  9.        android:strokeWidth="8" />
  10. </vector>
可以看到,总的来说 SVG 文件在 Android 中的载体是一个 <vector/> 标签,而绘制图片的工作是在 <path/> 这个子标签里面做的。我们先来看一下这两个标签里面最常使用的一些属性。

vector:

属性

参数类型

默认值 描述
width dimen 必填属性

图形的实际宽度,可在使用时根据需要再次定义 

height dimen 必填属性 图形的实际长度,可在使用时根据需要再次定义
viewportHeight float 必填属性 定义画布的尺寸
viewportWidth float 必填属性 定义画布的尺寸

基本上知道了上面这些属性就可以通过赋给 pathData 一些值来绘制出一些比较常规的图形了。接下来我讲一下在 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(S X2,Y2,ENDX,ENDY):三次贝塞曲线 
Q = quadratic Belzier curveto(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():关闭路径
另外,上述所有指令大小写均可。大写表示绝对定位,参照全局坐标系;小写表示相对定位,参照父容器坐标系。指令和数据间的空格可以省略。同一指令出现多次可以只用一个。

现在我们可以稍微的解读一下上面的那个例子里面的 pathData 是什么意思了。上面的数据是:
    M50,2 L80.813,2 L80.813,130 L50,130 L50,2 Z//大家可以看到,L 指令的后面只有一个坐标,这样的意思就是画的时候以上一笔的终点为起点

根据我们的语法,他的意思就是:
M 50,2 :将画笔移到(50,2) 坐标处。 
L 80.813,2 :从 (50,2) 画直线到 (80.813,2)。 
L 80.813,130 :从 (80.813,2) 画直线到 (80.813,130)。 
L 50,130 :从 (80.813,130) 画直线到 (50,130)。 
L 50,2 :从 (50,130) 画直线到 (50,2)。 
Z :结束这一笔。
我们不难发现,绘制的过程其实很简单,最后的结果是形成了一个闭合的矩形——和我们的成型的图像是一致的。
       在这里我就不介绍更多的指令的使用了,具体的大家可以参照这篇文章:Android vector标签 PathData 画图超详解。不过其实我认为,根本没有必要去把这些指令完全的记忆下来,因为在实际的工作中我们几乎是不会去手写 SVG 文件的,我们需要掌握的指令其实只有两个: M 和 Z 。因为它们象征着画笔的一笔的开始和结束,在涉及一些和路径轨迹相关的操作的时候我们可以合理的控制 M 和 Z 来很快速的达到我们的目的。

3.1.2,获取一个 SVG 文件(Android 中)

    在希望加入 SVG 文件的地方右键一下,然后 new -> Vector Asset :



点一下 Vector Asset ,会弹出另一个新的弹窗,它是长这样的:




       图中有两个白色框框起来的部位,上面那个是一个单选框,可以很清晰的知道选第一个是选取 Material Icon (没错,就是这么贴心,AS 自带所有 MD 图标的 SVG 文件),第二个是选取本地 SVG 文件,选好第一个框之后再在下面的白框里面选择具体的哪一个文件——这样一来,我们的目的就完成了,我们成功的在 AS 里面得到了一个 SVG 的 XML 文件。


      在这里可能很多同学会有一个问题:刚才说了如何将本地的 SVG 文件导入到 AS 中,那么我们又怎么获得本地的 SVG 文件呢?讲道理,这个问题不应该是我们考虑的,这个东西应当是美工把制作好的图给我们,然后我们直接使用就可以了。但是有的时候我们自己做小东西并没有专业的美工怎么办呢?要么你可以自己去学学 AI 或者 GIMP 等软件的使用方法, 用它们来制作图形然后导成 SVG ,当然这样的话学习成本有点高——不过没关系,我们还有低配版的实现方式:Method Draw。这是一个在线制作矢量图的网站,可以很方便的将在上面制作的图形导出成 SVG 文件,学习成本相当低,而且能完成我们大部分的需求,总之我觉得还挺好用的。

      如果前面的工作都完成了的话,我们应当是已经有了一个 SVG 的 XML 文件,接下来理所当然的是如何在我们需要的地方使用它了。那么怎么使用呢?


       我想说的是,接下来你完全可以把它当成我们引入项目的一张图片来用。比如:



      上图是直接在布局文件中直接引用 SVG 的 XML 文件,代码中的 ic_android_black_24dp 就是已经写好的 SVG 文件。可以看到,直接把它当做一张普通的图片来使用就可以了。当然,我们也可以在 Java 代码里面来使用 SVG 文件,像下面这样:


mImageView.setImageDrawable(getDrawable(R.drawable.ic_android_black_24dp));


      到这里我们就已经可以在 Android 中使用 SVG 来作为图片资源了,这样一来不仅 Apk 包的体积得到了大大的减小,我们的图片也具有了任意拉伸而不失真的特性,而且我们也再也不用非常痛苦的去搞图片改名称分包了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值