图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解

一、Vector优点

VectorDrawable主要有两个优点:屏幕自适应体积小

  • 如果我们使用的是普通的png或者jpg图片,那么为了能让图片在不同分辨率的机型上能够很好地展现,通常会在各个drawable文件夹下放置不同分辨率大小的图片文件,而VectorDrawable则不需要,仅仅只使用一套资源,就能够适应任何分辨率的手机。
  • 对于某些图片,VectorDrawable素材的大小要比pngjpg小很多。

二、SVGVector的基本概念

下面,我们先介绍一下SVGVectorDrawable的基本概念:

  • SVG:它并不是Android平台特有的概念,它的全称为可缩放矢量图形,简单的来说,就是用于描述二维矢量图形的图形格式,更加详细的解释可以参考:SVG - 百度百科。
  • VectorDrawable:它是Android当中的SVG实现,它并不支持SVG的全部语法,只是支持部分有必要的部分。

三、获取VectorDrawable

俗话说的好,巧妇难为无米炊,这一节我们就来介绍一下如何获得一个VectorDrawable,一般获取的方式有以下三种方式:

  • 先获取SVG素材,再通过工具转换成为VectorDrawable
  • 通过Android Studio中的素材库,直接获取VectorDrawable
  • 根据Vector的语法,自己描述

3.1 先获取SVG素材,再通过工具转换成为VectorDrawable

首先获取SVG素材,再将它转换成为VectorDrawable是最常用的方式,而SVG素材的获取又有以下几种途径:

  • 网站直接下载SVG图像
  • UI设计师使用专业的工具导出
  • 通过 VectorMagic 软件,将pngjpg素材转换为SVG图像

对于个人开发者而言,一般都会采用第一种方式,我们这里也只介绍第一种方式。很多文章都推荐过这个网站:iconFront - 阿里巴巴,它提供了SVGPNG素材的直接下载:

图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第1张图片

下载完毕之后,在 Android StudioNew选项中,选择 Vector Asset
图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第2张图片

打开之后,选择 Local file,并打开我们下载后的图像,再选择 next保存到指定的文件夹:
图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第3张图片

最后,我们会得到一个 *.xml文件,这个就是 VectorDrawable


    

3.2 通过Android Studio中的素材库,直接获取VectorDrawable

还是在上面的那个界面,我们勾选另外一个选项:

图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第4张图片

这里面有 Material Design提供的素材库:
图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第5张图片

通过这种方式,同样可以获取到一个 *.xmlVectorDrawable


    

3.3 根据Vector的语法,自己描述

3.13.2当中,我们可以看到,最终VectorDrawable都是用一个*.xml来表示的,那么,我们当然可以根据SVG的语法,来编写一个xml文件,通过pathData属性进行描述,不过这种方式较为繁琐,一般不会采用。

四、Vector语法

虽然说大多数情况下,我们不会完全手动去编写Vectorxml文件,但是,对于Vector的基本语法还是有必要了解一些的,因为在我们后边谈到的动态Vector中需要了解对于每个标签有哪些属性可以设置,Vector包含下面三种标签:


    
        
        
    

4.1 标签

  • name:矢量图的名字
  • width, height:矢量图的固有宽高,通常使用dp
  • viewportWidth, viewportHeight:把矢量图的宽高分成多少个单元,这里的每个单元就对应pathData中的一个点坐标。

4.2 标签

  • name:路径的名称。
  • fillColor:图形的填充颜色。
  • pathData:定义控制点的位置,类似与Canvas当中的Path类。

4.3 标签

用来把多个组合在一起,进行相同的处理。

更多的属性可以查阅下面这两篇文章:

VectorDrawable 详解
Android 中的 SVG 图像的各个属性意义

五、Vector的兼容性问题

为了让VectorDrawable能够在Android 5.0以下版本的手机上使用,我们需要引入support包,并修改gradle的配置。

5.1 引入support

VectorDrawable是在Android 5.0之后提出来的,因此,如果我们需要在低版本上使用,那么就要引入com.android.support:appcompat-v7包,要求版本号大于等于23.2.0,这里我们选用的是:

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

Vector相关的两个包为:

图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第6张图片

5.2 修改gradle配置文件

如果gradle的版本小于2.0

android {
    defaultConfig {
        generatedDensities = []
    }

    aaptOptions {
        additionalParameters "--no-version-vectors"
    }
}

如果gradle的版本大于2.0,例如我们所用的版本:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.0'
    }
}

那么需要这样配置:

android {
    defaultConfig {
         vectorDrawables.useSupportLibrary = true
    }
}

关于更多兼容性的问题,可以查看下面这篇文章

Android Vector 曲折的兼容之路

六、静态VectorDrawable

如果使用静态的方式展示VectorDrawable,那么很简单,只需要像使用普通的drawable一样,首先,我们按照第三节的方法,获取到一个vectorDrawable,并把它放在drawable文件夹下:


    

我们可以应用于:

  • ImageViewsrc
  • Viewbackground
  • TextViewdrawable


    
    
    

在上面的例子中,我们还使用了ic_account_circle_selector,其定义如下:



    
    

ic_account_circle_black_24dp就是之前获取到的素材,而ic_account_circle_black_normal_24dp就是改变了它的fillColor属性:


    

点击后的效果为:


图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第7张图片

七、动态VectorDrawable

动态的VectorDrawable,也就是AnimatedVectorDrawable,一般来说,它的整个结构如下图所示:

图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第8张图片

为了实现动态的 VectorDrawable,一般需要提供三种类型的 *.xml文件,这三个 xml文件的根标签分别为:

  • vector:图像资源,也就是我们上面讨论的静态vector,定义于res/drawable文件夹下。
  • objectAnimator:定义图像资源中个元素的动画行为,定义于res/anim文件夹下。
  • animated - vector:对vector中的元素与objectAnimator进行组合,定义于res/drawable文件夹下。

7.1 对标签进行动画

下面,我们先看一个简单的例子,上面我们所谈到的三个*.xml文件如下:

图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第9张图片

7.1.1 vector文件


    
        
    

这里我们生成了一个头像的Vector素材,它的图像如下,注意到,我们用一个group标签把path标签包裹起来,并且给它定义了一个name属性为group_account,这个属性在后面会用到。

7.1.2 objectAnimator文件



    

objectAnimator的定义和属性动画是相同的,我们需要指定需要变换的属性,也就是propertyName,并通过valueFrom/valueTo指定变化的起点值和终点值,这里我们选择了采用无限循环的方式来变换目标的rotation属性。

7.1.3 animated-vector文件


    

animated-vectorvector是一一对应的关系,因此需要在根标签中指定android:drawable,也就是在7.1.1中的vector文件。
而每一个target标签是内是成对的name - animation属性,name就是在7.1.1中声明的groupname,而animation则是在7.1.2中定义的动画文件。

如果objectAnimator所指定的属性在name所对应的标签中没有,那么不会发生任何变化。

7.1.4 启动动画

首先,在布局的xml文件中,把imageViewsrc指定为7.1.3中的animate-vector


    

在代码中,需要手动获得这个vectorDrawable,然后启动动画:

public class VectorDrawableActivity extends AppCompatActivity {

    private ImageView mAnimateView;
    private AnimatedVectorDrawable mAnimatedVectorDrawable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vector_drawable);
        mAnimateView = (ImageView) findViewById(R.id.iv_dynamic);
        mAnimatedVectorDrawable = (AnimatedVectorDrawable) mAnimateView.getDrawable();
        mAnimateView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mAnimatedVectorDrawable.start();
            }
        });
    }
}

效果如下:


图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第10张图片

7.2 对标签中的属性进行动画

7.1中,演示了如何对group标签的属性进行变换,下面,我们再演示一下如何对path标签中的属性进行变换。和前面类似,我们依然需要三种类性的*.xml文件

图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第11张图片

7.2.1 vector文件


    

这里,同样需要给path指定一个名字,用于后面和objectAnimator进行关联,它的素材为:

7.2.2 objectAnimator文件



    

这里,我们选择的是path标签下的trimPathEnd属性,它表示从Path终点的位置去除Path,与之对应的还有trimPathStart属性,它表示从Path起点的位置去除Path,而trimPathOffset则可以改变Path的起点,这三个值的取值范围都是0~1

7.2.3 animated-vector文件


    

效果如下:


图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第12张图片

7.3 之间切换

除了上面普通的属性之外,还支持对标签下的进行改变,系统会比较两个pathData之间的差别,并自动产生合适的动画。需要注意,它要求这两个pathData的点坐标的个数是相同的

7.3.1 Vector文件

这里,我们需要生成两个vectorDrawable,首先是起始的VectorDrawable


    

它的素材为:


接着是终点的 VectorDrawable


    

它对应的素材为:


7.3.2 objectAnimator文件



    

这里的propertyNamevalueType需要分别定义为pathDatapathType,而起点和终点的值就是我们在7.3.1生成的两个VectorDrawable所对应的pathData属性的值。

7.3.3 animated-vector文件


    

最终的效果为:


图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解_第13张图片

八、VectorDrawable的性能

关于VectorDrawable的性能问题,Android Vector 曲折的兼容之路 这篇文章说的很好,因此直接引用过来了:

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

九、参考文献

1. Android Vector 曲折的兼容之路
2. VectorDrawable 怎么玩
3. Android 使用矢量图(SVG, VectorDrawable)实践篇
4. SVG - 百度百科
5. Android 中的 SVG 图像的各个属性意义

你可能感兴趣的:(图片压缩知识梳理(6) - VectorDrawable 及 AnimatedVectorDrawable 使用详解)