Vector曲折的合作之路,SVG和Vector的定义和什么在Android

Android Vector曲折的拾贰分之路

两年前写书的时候,就在探讨Android
L指出的Vector,可切磋下来发现,完全不有所包容性,相信那也是它并未被普遍利用的多个原因,经过谷歌的不懈努力,今后Vector终于迎来了它的夏季。

4.jpg

在作品后边,会给出本文的德姆o和功力图,并开源在Github

    后日自家在看某脑SVG摄像和网上查资料时,发现了和某位大佬的写小说的某种巧合(报以神秘的笑颜)。因为性障碍,所以作者想计算性的抄袭一瞬。不论是还是不是被察觉,一切荣誉归属于大佬。
    抄袭对象大佬: Android
Vector曲折的匹配之路

Vector Drawable

Android 5.0发布的时候,谷歌(Google)提供了Vector的帮助。Vector
Drawable相对于一般的Drawable来说,有以下多少个好处:

  • Vector图像可以自动举行适配,不要求经过分辨率来设置不一致的图形
  • Vector图像可以小幅减弱图像的容积,同样一张图,用Vector来落成,或然唯有PNG的几十分一
  • 行使简便,很多安顿工具,都可以一直导出SVG图像,从而转换到Vector图像
  • 功用强大,不用写过多代码就可以兑现极度复杂的卡通片
  • 成熟、稳定,前端已经充裕普遍的拓展利用了

Vector图像刚公布的时候,是只协理Android 5.0+的,对于Android
pre-L的系统的话,并不可以接纳,所以,可以说那时候的Vector并不曾什么卵用。然则自从AppCompat
23.2随后,谷歌(Google)对p-View的Android系统也进展了拾贰分,约等于说,Vector可以运用于Android
2.1上述的富有系统,只须要引用com.android.support:appcompat-v7:23.2.0之上的本子就足以了,那时候,Vector应该算是迎来了它的秋季。

引导:

Android微信上的SVG

哪些获得Vector图像

概念

概念

首先,须求讲解多少个概念——SVG和Vector。

SVG,即Scalable Vector Graphics
矢量图,那种图像格式在前者中一度采纳的可怜普遍了,详见WIKI:https://en.wikipedia.org/wiki/Scalable\_Vector\_Graphics

Vector,在Android中指的是Vector
Drawable,相当于Android中的矢量图,详见:https://developer.android.com/reference/android/graphics/drawable/VectorDrawable.html

故此,可以说Vector就是Android中的SVG已毕,因为Android中的Vector并不是协理全部的SVG语法,也从未要求,因为完全的SVG语法是非凡复杂的,但一度支撑的SVG语法已经丰盛了,特别是Path语法,大概是Android中Vector的标配,详细能够参考:http://www.w3.org/TR/SVG/paths.html

SVG

    即Scalable Vector Graphics
可伸缩矢量图形,那种图像格式在前端中一度选用的那么些常见了。详见WIKI:https://en.wikipedia.org/wiki/Scalable\_Vector\_Graphics
    什么是矢量图像,什么是位图图像?

  • 矢量图像:SVG是W3C
    推出的一种开放标准的文本式矢量图形描述语言,他是依照XML的、专门为互连网而规划的图像格式,SVG是一种采纳XML来描述二维图形的言语,所以它可以直接打开xml文件来修改和编排。
  • 位图图像:位图图像的仓储单位是图像上每一点的像素值,因此文件会相比大,像GIF、JPEG、PNG等都是位图图像格式。
        在android开发中,无法一直动用SVG文件作为图片文件,否则就会这么:
![](https://upload-images.jianshu.io/upload_images/3161958-05ad81624f594f78.png)

不能直接复制svg文件到as里



    这个时候,我们就需要用到Vector。

Vector语法简介

Android以一种简化的主意对SVG进行了同盟,那种方法就是由此接纳它的Path标签,通过Path标签,大致可以兑现SVG中的其余具有标签,纵然大概会复杂一点,但那么些事物都以足以经过工具来完结的,所以,不用操心写起来会很复杂。

Path指令解析如下所示:

  1. 支撑的下令:
  • 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():关闭路径
  1. 采纳标准:
  • 坐标轴为以(0,0)为基本,X轴水平向右,Y轴水平向下
  • 具备指令大小写均可。大写绝对定位,参照全局坐标系;小写相对固化,参照父容器坐标系
  • 指令和数据间的空格可以回顾
  • 一如既往指令出现数次足以只用3个

瞩目,’M’处理时,只是活动了画笔, 没有画任李强西。
它也足以在前面给出上同时绘制不总是线。

关于这个语法,开发者需求的并不是一体融会贯通,而是可以看懂即可,其余的都可以交到工具来落到实处。

Vector

    在Android中指的是Vector
Drawable,相当于Android中的矢量图,可以说Vector就是Android中的SVG完成(并不是永葆任何的SVG语法,现已资助的完全充裕用了)详见:https://developer.android.com/reference/android/graphics/drawable/VectorDrawable.html
    补充:Vector图像刚揭橥的时候,是只帮忙Android
5.0+的,但是在此后,谷歌(Google)展开了合作:
1. Gradle Plugin 1.5的兼容
    从Gradle Plugin 1.5方始,谷歌(Google)协理了一种兼容格局,即在Android
L之上,使用Vector,而在L之下,则选择Gradle将Vector生成PNG图像。
    Android gradle plugin
1.5文告之后,出席了2个跟VectorDrawable有关的新功效。Android build tools
提供了其余一种缓解包容性的方案,借使编译的本子是5.0事先的本子,那么build
tools
会把VectorDrawable生成对应的png图片,这样在5.0之下的本子则利用的是浮动的png图,而在5.0以上的本子中则运用VectorDrawable.在build.gradle添加generatedDensities配置,可以配备生成的png图片的密度。
2. AppCompat23.2的兼容
    从com.android.support:appcompat-v7的版本为23.2.0起,Vector可以包容到Android
2.1以上的拥有系统,只须要

 compile 'com.android.support:appcompat-v7:23.2.0'//及以上

    23.2.0及以上的本子就可以了。
    注意事项:所谓的格外并非可以使用SVG了,本质如故生成了PNG图片来行使。

新葡萄娱乐 1

今非昔比版本的真相

从PNG到SVG

  • 设计师

要从一般采用的PNG图像转换成SVG图像,对于设计师来说,并不是一件难事,因为多数的宏图工具(PS、Illustrator等等)都帮助导出各类格式的图像,如PNG、JPG,当然,也包涵SVG,由此,设计师可以完全根据原有的法门展开设计,只是最终导出的时候,采用SVG即可。

  • 程序员

不需要开发者都去学习运用这个规划工具,开发者可以行使部分工具,自个儿转换一些相比较基础的图像,http://inloop.github.io/svg2android/
就是如此2个极度牛逼的网站,可以在线将平常图像转换为Android Vector
Drawable。如图所示:

5.png

要么,还是能使用SVG的编辑器来进展SVG图像的编写,例如http://editor.method.ac/

6.png

Vector Drawable:

    Android 5.0发表的时候,谷歌(Google)提供了Vector的支撑,即:Vector
Drawable类。
    Vector Drawable相对于一般的Drawable来说,有以下多少个便宜:

  • Vector图像可以自行进行适配,不要求经过分辨率来设置差别的图片,那在自身眼里是最好的地点。
  • Vector图像可以大幅度回落图像的体积,同样一张图,用Vector来促成,只怕唯有PNG的几一成,那从减少apk大小上很有含义,但有大佬发现,其实并不是截然就能减小,当PNG唯有十几k,用Vector反而变大了。
  • 应用简便,很多计划工具如PhotoShop、Illustrator,都得以一贯导出SVG图像,从而转换来Vector图像,够灵活,不用写过多代码就可以完毕相当复杂的卡通片。
  • 曾经沧海、稳定,前端已经不行常见的举办应用了。

使用Android Studio

选取Android Studio的Vector
Asset,可以充裕有利于的创导Vector图像,甚至足以一贯通过位置的SVG图像来生成Vector图像,如图所示:

2.png

进去将来,就可以生成Vector图像,如图所示:

3.png

Vector 语法简介

    Android以一种简化的措施对SVG举办了卓殊,那种艺术就是透过选择它的Path标签,通过Path标签,大约可以完成SVG中的其余具有标签,即使只怕会复杂一点,但这一个东西都以足以因此工具来成功的,所以,不用顾虑写起来会很复杂。

  • 帕特h指令解析如下所示:

M = moveto(M X,Y) :将画笔移动到指定的坐标位置,相当于 android Path 里的moveTo()
L = lineto(L X,Y) :画直线到指定的坐标位置,相当于 android Path 里的lineTo()
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):弧线 ,相当于arcTo()
Z = closepath():关闭路径(会自动绘制链接起点和终点)
  • 运用规则:
  1. 坐标轴为以(0,0)为中心,X轴水平向右,Y轴水平向下
  2. 负有指令大小写均可。大写相对定位,参照全局坐标系;小写相对固化,参照父容器坐标系
  3. 指令和数据间的空格可以归纳
  4. 一致指令出现反复得以只用3个

    注意事项

  1. ’M’处理时,只是活动了画笔, 没有画任何事物。
  2. 关于这么些语法,开发者不要求方方面面贯通,而是能够看懂即可,这个path标签及数据生里约热内卢可以付出美工工具和网上的网站来落实:
    1)可以接纳SVG的编辑器来开展SVG图像的编辑,例如:http://editor.method.ac/

    新葡萄娱乐 2

    SVG图像的编撰

2)有些网站可以找到SVG资源  
SVG下载地址:
[http://www.shejidaren.com/8000-flat-icons.html](https://link.jianshu.com?t=http://www.shejidaren.com/8000-flat-icons.html)  
[http://www.flaticon.com/](https://link.jianshu.com?t=http://www.flaticon.com/)  
阿里的iconfont
:[http://www.iconfont.cn/home/index?spm=a313x.7781069.1998910419.1](https://link.jianshu.com?t=http://www.iconfont.cn/home/index?spm=a313x.7781069.1998910419.1)  
我个人喜欢后面那个。  
3)对SVG文件用[http://inloop.github.io/svg2android/](https://link.jianshu.com?t=http://inloop.github.io/svg2android/)
生成 VectorDrawable xml代码  

![](https://upload-images.jianshu.io/upload_images/3161958-1a0b6da5a8bc7ddc.png)

上传图片文件到网站里



![](https://upload-images.jianshu.io/upload_images/3161958-5af26fd6b79f0e2c.png)

自动生成Vector的xml文件


4)使用Android Studio自带功能Vector Asset
Studio,完成SVG添加,将SVG文件转成Vector。  

![](https://upload-images.jianshu.io/upload_images/3161958-710905f3df95706e.png)

阿里的iconfont下载svg文件1



![](https://upload-images.jianshu.io/upload_images/3161958-8572cbb72482a8d4.png)

阿里的iconfont下载svg文件2



![](https://upload-images.jianshu.io/upload_images/3161958-d9f4e880e2a0bbb7.png)

image.png



![](https://upload-images.jianshu.io/upload_images/3161958-e35635a4e42189b6.png)

阿里的iconfont下载的svg文件



![](https://upload-images.jianshu.io/upload_images/3161958-87a3b6e0ae92cd7a.png)

as里选择Vector Asset



![](https://upload-images.jianshu.io/upload_images/3161958-26381130ccbbe985.png)

选择生成可用文件方式



![](https://upload-images.jianshu.io/upload_images/3161958-6f011134541d9926.png)

选择生成可用文件所在位置



![](https://upload-images.jianshu.io/upload_images/3161958-e44bd50c732ed3a9.png)

生成成功,查看效果


**补充**:也可参考网址[http://www.jianshu.com/p/d6c39f2dd5e7](https://www.jianshu.com/p/d6c39f2dd5e7)

谷歌(Google)的合作之路

静态Vector图像

  1. 生成图片
        例如: 咱们用as生成1个矩形

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="200dp"
        android:height="200dp"
        android:viewportHeight="500"
        android:viewportWidth="500">

    <path
        android:name="square"
        android:fillColor="#000000"
        android:pathData="M100,100 L400,100 L400,400 L100,400 z"/>
</vector>

新葡萄娱乐 3

矩形

    解释底部的多少个标签:
    android:width /android:height:定义图片的宽高
    android:viewportHeight /
android:viewportWidth:定义图像被划分的比重大小,例如例子中的500,即把200dp大小的图像划分成500份,后边Path标签中的坐标,就满门采取的是那里划分后的坐标连串。
    那样做有多少个非常好的效益,就是将图像大小与图像分离,前面可以随便改动图像大小,而不要求修改PathData中的坐标。

  1. 在控件中选取
  • 行使ImageView,就当普通的图片应用就足以了。

            <ImageView
                android:id="@+id/iv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:srcCompat="@drawable/vector_image"/>

    或许代码设置:

                ImageView iv = (ImageView) findViewById(R.id.iv);
                iv.setImageResource(R.drawable.vector_image);
                iv.setBackgroundResource(R.drawable.vector_image);//setBackgroundResource也是可以设置Vector的API

    注意事项

  1. 当自己的minSdkVersion
    小于21时,不在5.0+,则不只怕对Vector直接使用app:srcCompat,否则会报错,须要去build.gradle里去设置一下。前面会在合营里讲【1】。假如是minSdkVersion>=21,当然是不会报错的了。
![](https://upload-images.jianshu.io/upload_images/3161958-7a22244060e505fd.png)

需build里设置
  1. 应用的都是常见的ImageView,而从不改成AppcomatImageView,这是因为运用了Appcomat后,系统会自动把ImageView转换为AppcomatImageView。
  • 万一是Button,则不或者一向使用app:srcCompat来平昔利用Vector图像,需求经过Selector来进展应用,首先,成立八个图像,用于Selector的多个状态(写三个SVG的Drawable):

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

    万分简单,只是把常备的Selector中的图像换来了Vector图像而已,接下去,在Button中行使那么些Selector即可:

<Button
    android:id="@+id/btn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:background="@drawable/selector"/>

    然后运营时又会发觉有个相当的坑,也在底下讲【2】。

只兼容L+

Vector是在Android L中指出来的新定义,所以在刚先导的时候是只包容L+的。

动态Vector

    动态Vector才是Android Vector Drawable的重点。
    动态的Vector必要通过animated-vector标签来开展落到实处,它似乎三个粘合剂,将控件与Vector图像粘合在了共同,三个基础的animated-vector代码如下所示:

<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/XXXXX1">

    <target
        android:name="left"
        android:animation="@animator/XXXXX2"/>

</animated-vector>

    举例:

新葡萄娱乐 4

一先河为勾,后为叉的职能

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
                 android:drawable="@drawable/path_tick" >
    <target
        android:name="tickCrossGroup"
        android:animation="@animator/anim_path_tick2cross" />
</animated-vector>

    设置了始于显示时的“path_tick”Vector图像,然后,target目的是最后达成“anim_path_tick2cross”效果。
    注意事项

新葡萄娱乐 5

animated-vector注意事项

    animated-vector在Android
Studio中其实是会报错的,但这几个并不影响编译和运转,属于Android
Studio的Bug。

新葡萄娱乐 6

path_tick

    path_tick代码为:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:height="120dp"
        android:width="120dp"
        android:viewportWidth="24"
        android:viewportHeight="24">
    <group>
        <path
            android:name="tickCrossGroup"
            android:pathData="M19.6,7 L10.4,16.2 M4.8,13.4 L9,17.6"
            android:strokeColor="#000"
            android:strokeWidth="2"/>
    </group>
</vector>

    path_tick是目的Vector图像,相当于静态的Vector图像。
    可以窥见,那里的Vector图像有个group标签。group标签的效果有七个:

  • 对Path举办分组,由于大家后边须求针对Path进行动画,所以可以让拥有同等动画效果的帕特h在同三个Group中。
  • 进展动画效果,单个的path标签是平素不translateX和translateY属性的,由此无法使用性质动画来决定path
    translateY,而group标签是一些,所以大家必要先将相关的path标签成分包裹在一个个的group标签中。
        anim_path_tick2cross代码为为:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="300"
        android:propertyName="pathData"
        android:valueFrom="M19.6,7 L10.4,16.2 M4.8,13.4 L9,17.6"
        android:valueTo="M17.6,6.4 L6.4,17.6 M6.4,6.4 L17.6,17.6"
        android:valueType="pathType"/>
</set>

    anim_path_tick2cross实际上就是运用属性动画来促成的动画效果。
    android:propertyName属性名,上文里为pathData,指的是path_tick里的

 android:pathData="M19.6,7 L10.4,16.2 M4.8,13.4 L9,17.6"

    从 android:valueFrom动画效果到 android:valueTo。
    当然,也可以android:propertyName=”translationX”这样换其余卡通属性。
写好了动态Vector,作为动画,肯定是要开启执行动画。怎么搞?

  <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="anim"
            app:srcCompat="@drawable/path_tick2cross_anim"/>

 public void anim(View view) {
ImageView imageView = (ImageView) view;
AnimatedVectorDrawableCompat animatedVectorDrawableCompat = AnimatedVectorDrawableCompat.create(this, R.drawable.path_tick2cross_anim);
imageView.setImageDrawable(animatedVectorDrawableCompat);
        Drawable drawable = imageView.getDrawable();
        if (drawable instanceof Animatable) {
            ((Animatable) drawable).start();
        }
    }

    判断imageView的图样是个动图,即属于Animatable,则强转并运营动画。那样不再须要动态写代码动画来搞了,向美工女帝撒撒娇就好了。
    注意事项
:要是是七个SVG举办动画,path元素中从2个形象转变到另1个造型,那三个形象必须满意:要有一样的吩咐(command)个数(逗号分割开的为命令),并且每一种命令的参数个数也务必一致。

Gradle Plugin 1.5的兼容

从Gradle Plugin 1.5早先,Google扶助了一种兼容情势,即在Android
L之上,使用Vector,而在L之下,则应用Gradle将Vector生成PNG图像。

Android gradle plugin
1.5发表之后,加入了3个跟VectorDrawable有关的新功能。Android build
tools
提供了此外一种缓解包容性的方案,若是编译的本子是5.0之前的版本,那么build
tools
会把VectorDrawable生成对应的png图片,那样在5.0以下的版本则利用的是转变的png图,而在5.0上述的版本中则接纳VectorDrawable.在build.gradle添加generatedDensities配置,可以布置生成的png图片的密度。

本子兼容

    VectorDrawableCompat看重于AAPT的一些效益,它能保证近年来矢量图使用的拉长的性质ID,以便他们得以在L版本以前被引用。
    在Android
5.0以前使用Vector,必要aapt来对财富进行部分拍卖,这一进程可以在aapt的配备中展开设置,倘使没有启用那样1个flag,那么在5.0之下的配备上运转就会生出android.content.res.Resources$NotFoundException。

  1. 最要害的是添加appcompat的支撑,如:

compile 'com.android.support:appcompat-v7:25.3.1'

    同时,确保您利用的是AppCompatActivity而不是普普通通的Activity。

  1. 您须要在档次的build.gradle脚本中,增添对Vector包容性的支持,代码如下所示:
        使用Gradle Plugin 2.0以上:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

    使用Gradle Plugin 2.0以下,Gradle Plugin 1.5以上:

android {
  defaultConfig {
    // Stops the Gradle plugin’s automatic rasterization of vectors
    generatedDensities = []
  }
  // Flag to tell aapt to keep the attribute ids around
  aaptOptions {
    additionalParameters "--no-version-vectors"
  }

    那种包容情势实际上是先关闭AAPT对pre-L版本采取Vector的让步,即在L版本上述,使用Vector,而在L版本前,使用Gradle生成相应的PNG图片,generatedDensities这几个数组,实际上固然要生成PNG的图纸分辨率的数组,使用appcompat后就不须求这么了。

新葡萄娱乐 7

L版本的内外

    那就是缓解了【1】的难题。

  1. 本子不一样,对DrawableContainers包容性难题
        谷歌(Google)的一人开发者在博客中写到:

First up, this functionality was originally released in 23.2.0, but then we found some memory usage and Configuration updating issues so we it removed in 23.3.0. In 23.4.0 (technically a fix release) we’ve re-added the same functionality but behind a flag which you need to manually enable.

    实际上,他们的这些改变,就影响了类似DrawableContainers(DrawableContainers
which reference other drawables resources which contain only a vector
resource)那样的类,它的二个特出,就是Selector(StateListDrawable也是)。那些开发者在文中涉及的flag,就是上边的那段代码,放在Activity的眼下就可以了:

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

    开启这些flag后,你就足以平常使用Selector这样的DrawableContainers了。同时,你还开启了接近android:drawableLeft那样的compound
drawable的运用权限,以及RadioButton的行使权力,以及ImageView的src属性。
    那就是缓解了【2】的题目。

  1. 动态Vector动画包容性难题
        1) 向下包容难题
        一说到包容,就只可以涉及坑,差不离全体的为了合营而做的更动,都会留给一些不足填满的坑,动态Vector动画也不例外,就算谷歌已经对Vector图像进行了Android
    2.1以上的匹配,但对于动态Vector动画,依然有众多范围的,例如:
        Path Morphing,即路径变换动画,在Android
    pre-L版本下是无力回天利用的。
         帕特h Interpolation,即路径插值器,在Android
    pre-L版本只可以动用系统的插值器,不可能自定义。
        Path
    Animation,即路径动画,这些一般采纳贝塞尔曲线来取代,所以没有太大影响。
        2) 向上包容难题
        除了在低版本上的包容性难点,在L版本之上,也设有包容性难题,即一而再了AppCompatActivity的界面,即便直接设置ImageView的srcCompat,那么Path
    Morphing动画是无能为力生效的,因为默许的AppCompatActivity已经暗中认同使用ImageViewCompat给转换了,可是AnimatedVectorDrawableCompat是不协助Path
    Morphing动画的,所以,在AppCompatActivity界面里面就不行了。
        化解办法很粗略,即采用代码来给ImageView添加动画:

 ImageView imageView = (ImageView) view;
        AnimatedVectorDrawable morphing = (AnimatedVectorDrawable) getDrawable(morphing);
        imageView.setImageDrawable(morphing);
        if (morphing != null) {
            morphing.start();
        }

    注意:不要选择AnimatedVectorDrawableCompat即可。

  1. 抽取string包容难题
        开发者有时候为了代码简洁或者会把Vector图像中的pathData放到string.xml中,然后在Vector图像中援引string。
        但那种方法固然因此生成png来合作5.0之下机型的话,会报pathData错误,编译器不会去读取string.xml,只好把pathData写到Vector图像中,动画文件中也是均等。
  2. 其他包容难点
        其余拾贰分想得到、诡异、不可以明了的兼容性难点,只能通过版本文件夹的法子来拓展兼容了,例如drawable-v21和drawable,分别创立五个公文名相同的财富在八个文件夹下,那样在21之上版本,会动用drawable-v21的财富,而其余会采用drawable下的能源。
  3. 当下有了合作格局,不过,如故会有部分Vector动画是不可以包容Android
    pre-L版本的,只能包容L+。

AppCompat23.2的兼容

从AppCompat23.2初始,Google开始协助在低版本上利用Vector。

学习Vector

    大佬的Vector动画德姆o库,地址如下所示:
https://github.com/xuyisheng/VectorDemo
    那一个德姆o分为两局地,一部分是可以包容Android
pre-L版本和L+版本的Vector动画,另一部分(通过Actionbar的按钮切换)是不得不包容L+的Vector动画。
    注意事项:这么些能合营和不可以协作,是因为Vector动画自己的听从不可能在pre-L版本包容。不是代码没设置。
    各个Vector动画,基本都包蕴四局部情节,即:

Vector:图像资源
Animated-vector:动画、图像粘合剂
ObjectAnimator:动画资源
代码:启动动画

各种Vector动画通过那五个部分去开展辨析,就这个清楚了。
那里浮现下德姆o的职能图:

新葡萄娱乐 8

Demo

静态Vector图像

大家有诸多办法可以拿到这几个Vector,那么哪些利用它们啊,Android
5.0以上的接纳就不讲了,不太具有广泛代表性,大家从pre-L版本的卓殊开头做起。

VectorDrawable的本性难点:

  • Bitmap的绘图功效并不一定会比Vector高,它们有一定的平衡点,当Vector相比简单时,其效能是肯定比Bitmap高的,所以,为了保证Vector的高功能,Vector须要越来越简便易行,PathData尤其规范、精简,当Vector图像变得相当复杂时,就须求接纳Bitmap来代替了
  • Vector适用于ICON、Button、ImageView的图标等小的ICON,只怕是亟需的动画片效果,由于Bitmap在GPU中有缓存成效,而Vector并没有,所以Vector图像不可以做往往的重绘
  • Vector图像过于复杂时,不仅仅要注意绘制成效,早先化效能也是索要考虑的重中之重因素

pre-L版本包容

VectorDrawableCompat倚重于AAPT的局地效应,它能保全如今矢量图使用的丰盛的质量ID,以便他们可以被pre-L版本之前的引用。

在Android
5.0事先使用Vector,必要aapt来对财富拓展一些处理,这一经过可以在aapt的安插中开展设置,如若没有启用这样二个flag,那么在5.0之下的装置上运营就会发出android.content.res.Resources$NotFoundException。

第①,你须求在品种的build.gradle脚本中,增添对Vector包容性的支撑,代码如下所示:

使用Gradle Plugin 2.0以上:

android {

    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

使用Gradle Plugin 2.0以下,Gradle Plugin 1.5以上:

android {
  defaultConfig {
    // Stops the Gradle plugin’s automatic rasterization of vectors
    generatedDensities = []
  }
  // Flag to tell aapt to keep the attribute ids around
  aaptOptions {
    additionalParameters "--no-version-vectors"
  }
}

像前边提到的,这种包容方式实际是先关闭AAPT对pre-L版本接纳Vector的低头,即在L版本以上,使用Vector,而在pre-L版本上,使用Gradle生成相应的PNG图片,generatedDensities那一个数组,实际上就是要生成PNG的图纸分辨率的数组,使用appcompat后就不须求如此了。

当然,最要紧的恐怕添加appcompat的帮助:

compile 'com.android.support:appcompat-v7:23.4.0'

与此同时,确保您利用的是AppCompatActivity而不是平日的Activity。

参考

https://www.youtube.com/watch?v=wlFVIIstKmA&feature=youtu.be&t=6m3s
https://medium.com/@shemag8/animated-vector-drawable-e4d7743d372c\#.3vkt12j20
https://github.com/jpuderer/AnimatedButton
Android vector标签 PathData
画图超详解

Android
Vector曲折的协作之路

有个风风火火项目来了,所以留待以往再更进一步讨论。

Vector图像

1个骨干的Vector图像,实际上也是多个xml文件,如下所示:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="200dp"
        android:height="200dp"
        android:viewportHeight="500"
        android:viewportWidth="500">

    <path
        android:name="square"
        android:fillColor="#000000"
        android:pathData="M100,100 L400,100 L400,400 L100,400 z"/>

</vector>

显示如图所示:

7.png

此地要求表达下这里的多少个标签:

  • android:width \新葡萄娱乐, android:height:定义图片的宽高
  • android:viewportHeight \
    android:viewportWidth:定义图像被分开的比重大小,例如例子中的500,即把200dp大小的图像划分成500份,前边帕特h标签中的坐标,就总体施用的是此处划分后的坐标种类。

那样做有三个充足好的功能,就是将图像大小与图像分离,前面可以自由改动图像大小,而不需求修改PathData中的坐标。

  • android:fillColor:帕特hData中的那一个属性就不详细讲了,与Canvas绘图的属性基本相仿。

在控件中运用

有了静态的Vector图像,就足以在控件中使用了。

可以窥见,那里大家利用的都以常见的ImageView,好像并不是AppcomatImageView,那是因为使用了Appcomat后,系统会自行把ImageView转换为AppcomatImageView。

ImageView\ImageButton

对于ImageView那样的控件,要协作Vector图像,只须求将事先的android:src属性,换到app:srcCompat即可,示例代码如下所示:

<ImageView
    android:id="@+id/iv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@drawable/vector_image"/>

在代码中设置的话,代码如下所示:

ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setImageResource(R.drawable.vector_image);

setBackgroundResource也是可以安装Vector的API

Button

Button并不可以直接使用app:srcCompat来采取Vector图像,必要通过Selector来展开应用,首先,创造三个图像,用于Selector的多个状态,代码如下所示:

selector1.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportHeight="24.0"
        android:viewportWidth="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M14.59,8L12,10.59 9.41,8 8,9.41 10.59,12 8,14.59 9.41,16 12,13.41 14.59,16 16,14.59 13.41,12 16,9.41 14.59,8zM12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
</vector>

selector2.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportHeight="24.0"
        android:viewportWidth="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
</vector>

selector.xml

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

极度不难,只是把常备的Selector中的图像换到了Vector图像而已,接下去,在Button中运用这几个Selector即可:

<Button
    android:id="@+id/btn"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:background="@drawable/selector"/>

然后运维,如若您认为可以运作,那就是太天真了,都说了是同盟,怎么能没有坑呢,这里就是一个坑……

本条坑实际上是有历史渊源的,谷歌的一人开发者在博客中写到:

First up, this functionality was originally released in 23.2.0, but
then we found some memory usage and Configuration updating issues so
we it removed in 23.3.0. In 23.4.0 (technically a fix release) we’ve
re-added the same functionality but behind a flag which you need to
manually enable.

实际上,他们的这么些改变,就影响了类似DrawableContainers(DrawableContainers
which reference other drawables resources which contain only a vector
resource)那样的类,它的贰个鳌头独占,就是Selector(StateListDrawable也是)。这几个开发者在文中提到的flag,就是底下的那段代码,放在Activity的先头就足以了:

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

开启这么些flag后,你就足以健康使用Selector那样的DrawableContainers了。同时,你还开启了看似android:drawableLeft那样的compound
drawable的施用权力,以及RadioButton的运用权限,以及ImageView’s src属性。

RadioButton

RadioButton的Button同样可以定义,代码如下所示:

<RadioButton
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:button="@drawable/selector"/>

动态Vector基础

动态Vector才是Android Vector Drawable的精彩所在

动态的Vector须求经过animated-vector标签来举办落到实处,它就如3个粘合剂,将控件与Vector图像粘合在了一同,三个基础的animated-vector代码如下所示:

<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/XXXXX1">

    <target
        android:name="left"
        android:animation="@animator/XXXXX2"/>

</animated-vector>

骨子里那其中只有七个至关重借使亟需关怀的,XXXXX1和XXXXX2。三个切实的示范如下所示:

<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_arrow">

    <target
        android:name="left"
        android:animation="@animator/anim_left"/>

    <target
        android:name="right"
        android:animation="@animator/anim_right"/>

</animated-vector>

那边代表目的图像是drawable/ic_arrow,对left、right分别采纳了anim_left、anim_right动画。这里的name属性,就是在静态Vector图像中group大概path标签的name属性。

animated-vector标签在现行的Android
Studio中其实是会报错的,但那几个并不影响编译和运作,属于Android
Studio的Bug。

目的图像

XXXXX1是目标Vector图像,也等于静态的Vector图像,例如:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="120dp"
        android:height="120dp"
        android:viewportHeight="24.0"
        android:viewportWidth="24.0">

    <group android:name="left">
        <path
            android:fillColor="#FF000000"
            android:pathData="M9.01,14L2,14v2h7.01v3L13,15l-3.99,-4v3"/>
    </group>

    <group android:name="right">
        <path
            android:fillColor="#FF000000"
            android:pathData="M14.99,13v-3L22,10L22,8h-7.01L14.99,5L11,9l3.99,4"/>
    </group>

</vector>

可以窥见,这里的Vector图像比从前大家看见的要多了3个group标签。group标签的作用有几个:

  • 对Path举行分组,由于大家前面须要针对帕特h举行动画,所以可以让具备同等动画效果的Path在同多少个Group中
  • 拓展动画效果,单个的path标签是尚未translateX和translateY属性的,由此不可以运用性质动画来控制path
    translateY,而group标签是一些,所以大家须要先将相关的path标签成分包裹在四个个的group标签中.

卡通效果

XXXXX2实际上就是模板要达成的动画片,动画效果其实就是基础的脾性动画,例如:

anim_left.xml

<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"/>

anim_right.xml

<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"/>

在代码中接纳

ImageView imageView = (ImageView) findViewById(R.id.iv);
AnimatedVectorDrawableCompat animatedVectorDrawableCompat = AnimatedVectorDrawableCompat.create(
        this, R.drawable.square_anim
);
imageView.setImageDrawable(animatedVectorDrawableCompat);
((Animatable) imageView.getDrawable()).start();

动态Vector包容性难点

向下包容难点

一说到包容,就只可以提到坑,大约全体的为了合营而做的改动,都会留下一些不得填满的坑,动态Vector动画也不例外,纵然谷歌已经对Vector图像举办了Android
2.1以上的匹配,但对此动态Vector动画,依然有为数不少范围的,例如:

  • Path Morphing,即路径变换动画,在Android pre-L版本下是无力回天选用的。
  • Path Interpolation,即路径插值器,在Android
    pre-L版本只可以接纳系统的插值器,无法自定义。
  • Path
    Animation,即路径动画,那几个一般采纳贝塞尔曲线来替代,所以并未太大影响。

进步包容难题

除外在低版本上的包容性难点,在L版本上述,也设有包容性难题,即一连了AppCompatActivity的界面,假如一向设置ImageView的srcCompat,那么Path
Morphing动画是心有余而力不足生效的,因为暗许的AppCompatActivity已经暗中同意使用ImageViewCompat给转换了,可是AnimatedVectorDrawableCompat是不扶助帕特h
Morphing动画的,所以,在AppCompatActivity界面里面就不行了。

解决办法很简短,即拔取代码来给ImageView添加动画:

ImageView imageView = (ImageView) view;
AnimatedVectorDrawable morphing = (AnimatedVectorDrawable) getDrawable(morphing);
imageView.setImageDrawable(morphing);
if (morphing != null) {
    morphing.start();
}

留神不要选拔AnimatedVectorDrawableCompat即可。

抽取string包容难点

开发者有时候为了代码简洁只怕会把Vector图像中的pathData放到string.xml中,然后在Vector图像中援引string。

但那种情势借使因而生成png来同盟5.0以下机型的话,会报pathData错误,编译器不会去读取string.xml,只可以把pathData写到Vector图像中,动画文件中也是同一,那也是为了同盟做出的自作者捐躯呢,不得而知。

其它兼容难题

其余卓殊想得到、诡异、不或者知晓的包容性难题,只能够通过版本文件夹的主意来开展包容了,例如drawable-v21和drawable,分别成立八个公文名相同的资源在五个文件夹下,这样在21以上版本,会利用drawable-v21的能源,而其他会接纳drawable下的财富。

动态Vector进阶

用好ObjectAnimator

所谓Vector动画进阶,实际上就是在动用ObjectAnimator的一对品质,尤其是trimPathStart、trimPathEnd那多个针对Vector的质量(要专注pathData属性不般配pre-L)。

那两性子子的法定文档如下所示:

android:trimPathStart
The fraction of the path to trim from the start, in the range from 0 to 1.
android:trimPathEnd
The fraction of the path to trim from the end, in the range from 0 to 1.
android:trimPathOffset
Shift trim region (allows showed region to include the start and end), in the range from 0 to 1.

其实很粗略,就是1个图像的截取,设置贰个比重即可,即眼下绘制多少比例的图像,其他部分不绘制,Start和End分别就是从PathData的Start和End开首算,大家参考多少个例证就能领悟了。

理解Path Morph

Path
Morph动画是Vector动画的一个尖端应用,说到底,相当于多少个PathData的更换,可是那种转移并不是随心所欲的,对于七个PathData,它们能展开Path
Morph的前提是,它们有着同等个数的关键点,即八个途径的更换,只是关键点的坐标变化,领悟了这一个基本原理,完成Path
Morph就非凡简单了。

学习Vector

在Github上自身开源了二个Vector的卡通片德姆o库,地址如下所示:

https://github.com/xuyisheng/VectorDemo

以此德姆o分为两片段,一部分是足以包容Android
pre-L版本和L+版本的Vector动画,另一部分(通过Actionbar的按钮切换)是不得不包容L+的Vector动画。

各种Vector动画,基本都包罗四部分内容,即:

  • Vector:图像能源
  • Animated-vector:动画、图像粘合剂
  • ObjectAnimator:动画财富
  • 代码:运转动画

各样Vector动画通过那两个部分去开展解析,就老大清晰了。

此间突显下德姆o的功力图:

vector.gif

Vector质量难点

有读者在小说前边留言,询问VectorDrawable的性质问题,那里解释一下。

  1. Bitmap的绘图效能并不一定会比Vector高,它们有自然的平衡点,当Vector相比简单时,其功能是必定比Bitmap高的,所以,为了有限支撑Vector的高成效,Vector需求更为简明,帕特hData特别正规、精简,当Vector图像变得非凡复杂时,就须要使用Bitmap来代替了
  2. Vector适用于ICON、Button、ImageView的图标等小的ICON,大概是亟需的卡通片效果,由于Bitmap在GPU中有缓存功能,而Vector并没有,所以Vector图像不或然做往往的重绘
  3. Vector图像过于复杂时,不仅仅要专注绘制效能,伊始化功用也是必要考虑的主要成分
  4. SVG加载速度会快于PNG,但渲染速度会慢于PNG,毕竟PNG有硬件加快,但平均下来,加载速度的升官弥补了绘图的速度缺陷。
    谷歌的那一个录像中,已经对Vector的频率难题做了表明,可以参照下:

https://www.youtube.com/watch?v=wlFVIIstKmA&feature=youtu.be&t=6m3s

参考

https://medium.com/@shemag8/animated-vector-drawable-e4d7743d372c\#.3vkt12j20
https://github.com/jpuderer/AnimatedButton