Android动画——Vector解析

参考:http://www.jianshu.com/p/e3614e7abc03, eclipse_xu

对于图像数据来说,可以分为矢量和栅格数据,矢量数据是记录绘制图形的方式,栅格数据是以像素点为组织形式拼接成一个图形。从这也能看出矢量和栅格数据的各个优缺点:

  1. 矢量数据:占用内存小,图像清晰度不受影响。但是绘制图形效率较低,通过CPU绘制。
  2. 栅格数据:占用内存大,图像清晰度会受图像拉伸而改变。但是通过GPU绘制,效率较高。

对于Android系统,在5.0版本时Google推出了Vector来使用矢量数据。下面简单介绍一下在Android中Vector的用法和注意事项。

1. Vecotr简介

1.1 SVG与Vector差异

SVG -- 前端中使用,是一套语法规范;

Android动画——Vector解析_第1张图片
SVG实例

vector -- 在Android中使用,vector只实现了SVG语法的path标签,为了提高解析效率。

1.2 Vector常用语法

M = moveto(M X,Y):将画笔移动到指定的坐标位置
L= lineto(L X, Y):画直线到指定的坐标位置
Z = closepath():关闭路径
H = horizontal lineto(H X): 画水平线到指定的X坐标位置
V = vertical lineto(V Y):画垂直线到指定的Y坐标位置

Android动画——Vector解析_第2张图片
实例——画一个矩形

1.3 常用工具

SVG编辑器

Android动画——Vector解析_第3张图片

SVG转换成vector

Android动画——Vector解析_第4张图片

阿里巴巴矢量图标库

Android动画——Vector解析_第5张图片

1.4 PNG、SVG、Vector效果对比

svg、Vector的优点:体积小,支持按比例缩放


Android动画——Vector解析_第6张图片
PNG、SVG、Vector效果对比

2. Vector使用

在下面的介绍使用方法时,是基于sdk6.0的,对于兼容性问题在2.4章节由所介绍。

2.1 添加Vector

在AndroidStudio中,有两种方式直接添加转换成Vector
右键drawable文件夹,选择new,选择Vector assert,


Android动画——Vector解析_第7张图片

其中一种是通过使用系统库的icon图标转换成Vector,一种是导入本地的SVG文件转换成Vector


    

除了自动转换,还可以手动编写一个Vector。在drawable文件夹中新建一个xml文件,然后使用vector和内部的path进行绘制。其中pathData的内容是一个矩形的路径。


    

Android动画——Vector解析_第8张图片

2.2 使用静态Vector

添加完Vector文件之后,在layout布局文件添加一个ImageView来展示这个Vector,使用的是app:srcCompat来引用资源文件。


Android动画——Vector解析_第9张图片

我们尝试在Button上设置上面的Vector资源,会发现无法设置。

Android动画——Vector解析_第10张图片

可以看到,在Button上用Vector是不生效的,原因是Google工程师对Vector的兼容性做出的妥协,因为Button是带有状态的控件,无法直接使用Vector。解决的办法就是使用selector插值器来配合使用。




    

然后在Button控件中使用background属性

        
Android动画——Vector解析_第11张图片

如果想要将图形增大,无需修改pathData属性,只修改android:viewportWidth和android:viewportHeight属性就可以了。

2.3 使用动态Vector

之前提到过Vector与其他栅格图像的区别,内存小、不失真,但这些并不是使用Vector的理由,其实使用Vector就是为了能够方便动态地添加动画效果。下面就以几个典型的例子来分析如何添加动态地Vector。

2.3.1 直线运动动画

Android动画——Vector解析_第12张图片
1.gif

实现如图所示的动画效果。

首先在drawable文件夹下创建图片的Vector资源文件:


    
        
    
    
        
    

此处由于是需要两个箭头的同时动画,这就需要为两个箭头添加不同的属性动画,所以,用group的方式进行组织,并且添加了name字段来标明。

添加完代码,可以看到是一个静态的双箭头图片。


Android动画——Vector解析_第13张图片
arrow

接下来,创建两个属性动画文件,分别对应向左和向右的动画效果。




简单说明一下,android:propertyName="translateX"意味着在X轴方向上运动, android:interpolator被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复),bounced(弹跳)等。"@android:interpolator/overshoot"指的是向前甩一定值后再回到原来位置。android:valueFrom="0"和android:valueTo="10"表示着效果的变化范围,对应来说是x轴上的移动位置变化,这段代码展示的是左面的箭头向右移动,相对应的右面的箭头向左移动就是android:valueFrom="0"和android:valueTo="-10"。android:valueType="floatType"指明了是运行距离的floatType类型。

然后在drawable文件夹下创建Vector动画的“粘合剂”——:



    
    

此处首先指明了 android:drawable代表图片的Vector的资源,然后在target标签下对每一个动画进行绑定,其中的name是之前的Vector图片资源文件里面的group的name属性。

最后,在粘合剂绑定完成后,用ImageView来承载这个粘合剂:

        

在Activity中实现这个点击事件,让动画启动:

    public void anim(View view) {
        ImageView imageView = (ImageView) view;
        Drawable drawable = imageView.getDrawable();
        if (drawable instanceof Animatable) {
            ((Animatable) drawable).start();
        }
    }

这样就能显示出我们想要的动画效果了。

2.3.2 颜色渐变动画

Android动画——Vector解析_第14张图片

接下来介绍一下颜色渐变动画的实现。

与上面的流程类似,首先创建Vector图片资源文件:


    

是一个静态的矩形


Android动画——Vector解析_第15张图片
矩形

然后在animator文件下创建对应的属性动画文件anim_square.xml:




此处android:propertyName="fillColor"指的是动画效果是填充颜色, android:valueFrom="@android:color/holo_red_dark"和android:valueTo="@android:color/darker_gray"指的是颜色的变化范围,并且值的类型是int。

然后是创建粘合剂square_anim.xml:



    

最后在ImageView上承载即可,就不多介绍了。

2.3.3 轨迹动画

主要介绍两种实现,一种是通过android:propertyName="trimPathStart",取值从0到1,表示路径从哪里开始绘制。0~trimPathStart区间的路径不会被绘制出来。一种是通过android:propertyName="pathData"定义路径的数据,路径由多条命令组成,格式与SVG标准的path data的d属性完全相同,路径命令的参数定义在viewport视图的坐标系,也就是说需要编写SVG格式的路径语句。

首先介绍第一种,看如下动画显示:


Android动画——Vector解析_第16张图片
1.gif

Android动画——Vector解析_第17张图片
2.gif

(1)搜索框动画
首先同样地创建Vector资源图片searchbar.xml:


    
    

分为放大镜图标和下划线图标。

接下来就是重点的显示动画
anim_search.xml:




anim_bar.xml




根据上面的定义介绍,anim_search.xml表示的是动画效果是绘制路径从有到无的变化过程,anim_bar.xml表示的是动画效果是绘制路径从无到有的变化过程。

同样地,创建粘合剂searchbar_anim.xml:



    
    

最后在ImageView中承载就可以实现上面的动画效果。

(2)星图标动画
这个动画包含两个属性动画,一个是颜色的渐变,一个是路径的变化。

Vector资源文件:


    
        
    

Android动画——Vector解析_第18张图片
path

重点是动画文件
anim_path.xml:



    
    

    
    

通过set标签包含两个objectAnimator,两个动画同时展示出来。

最后是粘合剂path_anim.xml



    

第二种,通过指定SVG路径语句


Android动画——Vector解析_第19张图片
5.gif

Vector资源图片fivestar.xml:


    
        
    

Android动画——Vector解析_第20张图片
fivestar

重点是动画文件anim_fivestar.xml:




着重解释一下,选用的是android:propertyName="pathData"属性,意味着需要添加图形的SVG格式运动轨迹,其中android:valueFrom是五角星,android:valueTo是五边形,所以运动轨迹就是从五角星到五边形的过程。

粘合剂代码fivestar_anim.xml:



    

最后添加ImageView来承载粘合剂即可。

2.3.4 总结

  1. 创建Vector图片资源文件,这个文件可能是UI设计师提供的,也可以在阿里矢量素材库等网站上获取的;
  2. 确定想要的动画效果,添加属性动画;
  3. 创建粘合剂,绑定动画和Vector资源;
  4. 用ImageView、ImageButton等控件承载粘合剂;
  5. 在Activity中启动动画。

2.4 Vector兼容性问题

Vector默认支持5.0以上版本,在AppCompat23.2以上版本支持向下兼容:
静态Vector支持Android2.1以上
动态Vector支持Android3.0以上
几乎可以兼容大部分使用场景

2.4.1 Button兼容

在上面讲到过,在Button上使用Vector必须通过Selector来完成的,在向下兼容时,需要在Activity的前面加上:

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

为了向下兼容,影响了类似DrawableContainers(DrawableContainers which reference other drawables resources which contain only a vector resource)这样的类。它的一个典型,就是Selector(StateListDrawable也是),这个属于Google工程师对于向下兼容的无奈之举吧。

2.4.2 动态兼容

(1)向下兼容
Path Morphing,即路径变换动画,(举例来说,圆形变矩形,五角星变五边形)在Android pre-L版本下是无法使用的。目前此问题是动态兼容上最大的问题。
Path Interpolation,即路径插值器,在Android pre-L版本只能使用系统的插值器,不能自定义。
Path Animation,即路径动画,这个一般使用贝塞尔曲线来代替,所以没有太大影响。
(2)向上兼容
因为考虑到兼容性的问题,会使用AppCompat库做兼容性工作。
例如,继承了AppCompatActivity,在布局文件中又指定了ImageView的srcCompat,但是AnimatedVectorDrawableCompat是不支持Path Morphing动画的。解决的方法是,判断当前设备版本号,如果是L版本以下提示不支持此动画,如果在L版本以上修改为如下代码:

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

(3)String.xml问题
不支持将Vector的PathData的数据,添加到String.xml中。

2.5 Vector属性介绍

2.5.1 Vector内部标签属性

属性 解析
android:name 定义该drawable的名字
android:width 定义该 drawable 的内部(intrinsic)宽度,支持所有 Android 系统支持的尺寸,通常使用 dp
android:height 定义该 drawable 的内部(intrinsic)高度,支持所有 Android 系统支持的尺寸,通常使用 dp
android:viewportWidth 定义矢量图视图的宽度,视图就是矢量图 path 路径数据所绘制的虚拟画布
android:viewportHeight 定义矢量图视图的高度,视图就是矢量图 path 路径数据所绘制的虚拟画布
android:tint 定义该 drawable 的 tint 颜色。默认是没有 tint 颜色的
android:tintMode 定义 tint 颜色的 Porter-Duff blending 模式,默认值为 src_in
android:autoMirrored 设置当系统为 RTL (right-to-left) 布局的时候,是否自动镜像该图片。比如 阿拉伯语。
android:alpha 该图片的透明度属性

2.5.2 path标签属性

属性 解析
android:name 定义该 path 的名字,这样在其他地方可以通过名字来引用这个路径
android:pathData 和 SVG 中 d 元素一样的路径信息。
android:fillColor 定义填充路径的颜色,如果没有定义则不填充路径
android:strokeColor 定义如何绘制路径边框,如果没有定义则不显示边框
android:strokeWidth 定义路径边框的粗细尺寸
android:strokeAlpha 定义路径边框的透明度
android:fillAlpha 定义填充路径颜色的透明度
android:trimPathStart 从路径起始位置截断路径的比率,取值范围从 0 到1
android:trimPathEnd 从路径结束位置截断路径的比率,取值范围从 0 到1
android:trimPathOffset 设置路径截取的范围 Shift trim region (allows showed region to include the start and end), in the range from 0 to 1.
android:strokeLineCap 设置路径线帽的形状,取值为 butt, round, square.
android:strokeLineJoin 设置路径交界处的连接方式,取值为 miter,round,bevel.
android:strokeMiterLimit 设置斜角的上限,Sets the Miter limit for a stroked path.

3. VectorDrawable使用场景

    1. Bitmap的绘制效率并不一定会比Vector高,它们有一定的平衡点,当Vector比较简单时,其效率是一定比Bitmap高的。所以,为了保证Vector的高效率,Vector需要更加简单,PathData更加标准、精简,当Vector图像变得非常复杂时,就需要使用Bitmap来代替。
    1. Vector适用于ICON、Button、ImageView的图标等小的ICON,或者是需要的动画效果。由于Bitmap在CPU中有缓存功能,而Vector并没有,所以Vector图像不能做频繁的重绘。
    1. Vector图像过于复杂时,不仅仅要注意绘制效率,初始化效率也是需要考虑的重要因素
    1. SVG加载速度会快于PNG,但渲染速度会慢于PNG,毕竟PNG有硬件加速,但平均下来,加载速度的提升弥补了绘制的速度缺陷。

总结来说,Vector更适用于小的控件,Button,ImageView等,有更加炫的动画效果。

你可能感兴趣的:(Android动画——Vector解析)