之前对矢量图形有所耳闻,但因为Android对于矢量图形的原生支持较晚,所以一直没好好研究过(16年2月25就出来的东西,其实就是懒 =。=)。最近工作上正好遇到一个产品需求,想用SVG来解决,借此机会对SVG及Android对于矢量图形的支持做了次了解,当然最后依然被SVG坑到,变成手写XML来解决需求,不过这都是题外话了。

SVG是什么?

Scalable Vector Graphics(可缩放矢量图形)是基于XML,用于描述二维矢量图形的图形格式。SVG由W3C制定,是一个开放标准。SVG本身允许包含3种图形对象类型:

  1. 矢量图形,包括矩形、圆、椭圆、多边形、直线、任意曲线等。
  2. 嵌入外部图像,包括png、jpeg、svg等。
  3. 文本。
    [from wikipedia]

以下是一个简单的SVG格式示例:

<?xml version="1.0" standalone="no"?>    

SVG是通过标签的形式来描述图形,比如矩形、圆形、多边形等等普通标签,以及支持复杂的路径的标签.其中Path标签可以通俗的理解为是用命令的方式来控制画笔,比如:
** 将画笔移动到指定坐标位置 -> 画一条直线到指定坐标位置 -> 再画一条曲线 -> 完成后抬起画笔结束**

当然Path标签也需要对应的指令来完成操作,比如:
M150 0 L75 200 L225 200 Z

下面是Path支持的对应指令:

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 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():关闭路径注意:以上所有命令均允许小写字母。大写表示绝对定位,小写表示相对定位。

当然,以上只是SVG中很小的一部分,还有其他很多强大的功能。SVG本身已经被广泛使用,SVG矢量图与位图的差别,在于矢量图可以尽可能的放大而不失真,并且同一张图像,SVG的实现可能比png小很多。如果在精简安装包的时候,可以考虑部分图标改成矢量图的方式。

Android中的矢量图替身Vector

Android中对于矢量图形的处理,并没有选择直接支持SVG文件,所以云端返回的svg格式图片是无法直接被显示的。
不过在Android 5.0中提出了矢量图片的支持,叫做Vector。通过创建标签的xml元素来完成对矢量图形的定义。

    android:height="256dp"    android:width="256dp"        android:viewportWidth="32"    android:viewportHeight="32">    

Android Studio从1.4版本开始,包含了一个Vector Asset Studio的工具,可以选择导入SVG或者PSD文件来帮助我们生成对应的vector xml文件。
工具本身支持大多数主体元素,但并不包含所有的SVG或PSD特性。SVG导入后的vector xml格式主体参考的是SVG中的pathdata语法,但虚线等属性、科学计数法、图案填充(pattern)、渐变(gradient)等特定标签是不支持的。当然Vector Asset Studio在我们导入的时候会有明确的提示哪些是被支持的、哪些是不被支持的。

以下两种方法都可以打开Vector Asset Studio:
1. 对应的drawable目录上右键 -> New -> Vector Asset



2. File -> New -> Vector Asset


Android项目中如何使用Vector?

从Android 5.0开始,系统提供了两个Api来完成对Vector的支持:

  1. VectorDrawable
  2. AnimatedVectorDrawable
    VectorDrawable负责矢量图形的显示,而AnimatedVectorDrawable负责基于矢量图形的动画效果。

与此同时,Android Support Library 23.2.0及之后的版本中,也加入了对Vector的向下兼容,引入了VectorDrawableCompat和AnimatedVectorDrawableCompat。

只需要引入对应的AppCompat库

compile 'com.android.support:appcompat-v7:23.2.0' VectorDrawable API 7+AnimatedVectorDrawable API 11+

另外需要在 build.gradle 文件中新增如下配置:

//For Gradle Plugin 2.0+ android {   defaultConfig {     vectorDrawables.useSupportLibrary = true    } }
//For Gradle Plugin 1.5 or belowandroid {  defaultConfig {    // Stops the Gradle plugin’s automatic rasterization of vectors    generatedDensities = []  }  // Flag notifies aapt to keep the attribute IDs around  aaptOptions {    additionalParameters "--no-version-vectors"  }}

如何使用VectorDrawable?

在布局文件中,我们可以针对ImageVIew、ImageButton等控制设置对应的矢量图片。

如果用的Support包,那只需要通过app:srcCompat=“”属性来替代以前的android:src即可。
另外记得添加xmlns:app="http://schemas.android.com/apk/res-auto"

如果使用的是Andorid5.0以上的原生支持,可以直接使用android:src=“”来完成对应的展现。

如何使用AnimatedVectorDrawable?

AnimatedVectorDrawable其实是针对Vector里面的各种元素,提供了属性动画的支持方式,从而完成对应的动画效果。

借用官方文档里的例子,如果采用多个xml来实现:
VectorDrawable's XML file: vd.xml

            

AnimatedVectorDrawable's XML file: avd.xml

     

Animator XML file that is used in the AnimatedVectorDrawable's XML file: rotation.xml

最后在布局中的使用方法,跟使用VectorDrawable是一样的:

<?xml version="1.0" encoding="utf-8"?>    

当然到此为止还有最重要的一步,否则看到的还只是静态的矢量图形:

ImageView demoView = (ImageView) findViewById(R.id.imageview);        if(demoView.getDrawable() instanceof Animatable){            ((Animatable) demoView.getDrawable()).start();        }

上面是多xml的例子,相当于矢量图形、动画目标、动画规则是分开的。还有一种方式是用单一的xml文件来描述整个矢量动画资源,需要Build Tools 版本在24及以上:

<?xml version="1.0" encoding="utf-8"?>                                                                                                    

因为AnimatedVectorDrawable改变的是vector中各元素的属性值,所以极大的增添了动画的实现手段及效果。

不过坑依然有,当API < 21时,扩展包中的AnimatedVectorDrawableCompat会有一些限制:

Path Morphing (PathType evaluator) Used to morph one path into another path.

Path Interpolation Used to define a flexible interpolator (represented as a path) instead of the system-defined interpolators like LinearInterpolator.

Move along path The geometry object can move around, along an arbitrary path, as part of an animation.

在此限制下,最能发挥效果的pathdata路径动画基本就可以忽略了。至少在发此文章的时候以上限制还在,只能默默期待以后吧。

总结

此文只是初略的讲述了Android中矢量图形的基础使用方法,当然深入来讲其实还有很多东西,包括第三方的一些SVG库、矢量动画的一些高级用法等等。在此只是做一个用法的基本记录,同时希望也是借此机会抛砖引玉,给大家提供一个新的处理思路吧。

原文链接: Android中矢量图形的那些事 - SVG or Vector

更多相关文章

  1. Android(安卓)- 支持不同的设备 - 支持不同的屏幕
  2. [置顶] android图形系统详解六:View layer
  3. Android(安卓)API Guiede---Animation and Graphics
  4. 9个非常棒的Android代码编辑器 移动开发者的最爱
  5. (六)android recovery 升级UI显示之资源文件
  6. [置顶] Android(安卓)fragment 只让一个fragment支持横屏
  7. 2013新春奉送:Android摄像头开发完美demo---(循环聚焦,缩放大小,
  8. Android上使用OpenGL画3D菱形
  9. Android多分辨率支持以及各种类型图标尺寸大小

随机推荐

  1. 初学Android,使用Drawable资源之使用Stat
  2. WebView用法与JS交互
  3. android简单的答题游戏
  4. Android自动化编译设置AndroidManifest.x
  5. 【转】Android(安卓)用户事件输入路径(Me
  6. Android手势:单指拖动、双指缩放图片
  7. Android布局属性android:clipToPadding的
  8. [无线] 让Android支持cmwap上网
  9. Android(安卓)XML解析器的问题
  10. Android(安卓)SystemProperties