一、矢量图简介
最近在进行Android App“瘦身 ”的时候,了解到矢量图(VectorDrawable)相关概念。
从Android5.0(API level 21)开始,有两个类支持矢量图:VectorDrawable和AnimatedVectorDrawable。VectorDrawable是一个矢量图,定义在一个XML文件中的点、线和曲线,和它们相关颜色的信息集合。AnimatedVectorDrawable是矢量图动画,使用多个XML文件而不是针对不同分辨率使用多个图片来实现动画。
使用矢量图主要有如下两个优:
  图片扩展性:它可以进行缩放并且不损失图片的质量,这意味着使用同一个文件对不同屏幕密度调整大小并不损失图片的质量;
  图片大小小:同样大小和内容图片下相比,矢量图比PNG图片更小,这样就能得到更小的APK文件和更少的维护工作;
然而,系统渲染VectorDrawable需要花费更多时间。因为矢量图的初始化加载会比相应的光栅图片消耗更多的CPU周期,但是两者之间的内存消耗和性能接近。因此我们可以只考虑在显示小图片的时候使用矢量图(建议你限制矢量图在200*200dp),越大的图片在屏幕上显示会消耗更长的时间进行绘制;

二、VectorDrawable
1.VectorDrawable简介

VectorDrawable定义了一个静态Drawable对象。和SVG格式非常相似,每个Vector图形被定义成一个树型结构,它由path和group对象组成。每条path包含对象轮廓的几何形状,每个group包含了变化的详细信息。所有path的绘制顺序和它们在XML出现的顺序相同;

2.VectorDrawable XML文件生成
Android Studio包含一个称为Vector Asset Studio的工具,它提供了一个简单的方法将矢量图以XML文件的形式添加到项目中。支持如下两种方式:
  添加Meterial Icon;
  导入可拉伸矢量图(SVG)和Adobe Photoshop文档(PSD)文件;
启动Vector Asset Studio
Android Studio->项目窗口->Android视图->选择res目录->New->Vector Asset(Android Plugin for Gradle 1.5.0或者更高);


使用Meterial Icon
Google meterial Design规范提供了meterial icons,你可以在你的Android app中使用。Vector Asset Studio帮助你选择,导入和设置meterial icon大小,定义透明度和Right-to-Left(RTL)镜像设置;

选择Meterial Icon->点击Icon按钮->Select Icon对话框(右边)->选择导入图片->OK,根据你的需要改变资源名称,大小,透明度和Right-To-Left镜像设置,点击Next按钮:

根据你的需要改变模块和资源目录,点击Finish按钮:

在app/src/main/res/drawable目录下,Vector Asset Studio添加了一个定义了适量图片的XML文件ic_assignment_ind_black_24dp.xml;

使用本地文件(SVG,PSD)
Vector Asset Studio也可以让你导入你自己的SVG和PSD文件。SVG是W3C一个基于XML的开源标准,PSD文件格式支持Adobe Photoshop。它支持基本的标准,但不支持所有的SVG和PSD功能。当你选择一个SVG或者PSD文件,它会立即给出是否支持图形编码的反馈。尽管矢量图支持一个或者更多的色彩,在许多场景下使用黑色图标(android:fillColor="#FF000000")。使用这种方式,你可以给你填充在布局中的矢量图添加一个tint,然后图标的颜色变成tint的颜色。如果图标的颜色不是黑色,图标的颜色可能和tint颜色混合;
选择Local file(SVG,PSD)->点击Path更多按钮->选择你要导入的图片->点击OK按钮->根据你的需要修改资源名称、大小、和透明度等属性->点击Next按钮(如果SVG或者PSD文件有一下不支持的功能,在Vector Asset Studio底部Errors会显示错误信息);

同上,根据你的需求改变资源输出的模块和目录->点击Finish按钮即可;

3.VectorDrawable使用
这里我们就简单使用一个Demo进行演示,显示两个图片和一个动画,目录如下:

构建兼容性配置
在Android 5.0之前(API level 21),Support Library 23.2或者更高的版本提供了矢量图片和矢量图片动画完整的支持。Android5.0之前的版本不支持矢量图,如果你支持最小API level是这些版本,你有如下两个选择:
  生成PNG文件;
  使用Support library;
为了在运行Android5.0(API level 21)之前版本设备不支持矢量图片和矢量图片动画,VectorDrawableCompat和AnimatedVectorDrawableCompat通过两个新的Support Libraries:support-vector-drawable和animated-vector-drawable分别进行支持;
在你app模块的build.gradle文件中添加vectorDrawables元素,使你的app使用矢量图support library;
flight/build.gradle文件

apply plugin: 'com.android.library'
android {... ...defaultConfig {... ...vectorDrawables.useSupportLibrary = true}... ...
}
dependencies {... ...compile 'com.android.support:appcompat-v7:25.0.1'
}

打包完成后,我们分析下APK打包了矢量图的xml文件;

我们也可以采用低版本构建生成PNG图片的兼容方式;
flight/build.gradle文件

apply plugin: 'com.android.library'
android {... ...aaptOptions {additionalParameters "--no-version-vectors"}... ...
}

打包完成后,我们分析下APK发现xml文件对应生成了对应png图片;

VectorDrawable定义
只需要一个资源文件(如上使用Vector Asset Studio导入)就可以创建矢量图片,而位图图片需要为每个屏幕密度提供一个文件。如果要创建一个矢量图片,在<vector>XML元素中定义如下:
flight/src/main/res/drawable/heart.xml文件

<vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="100dp"android:height="100dp"android:viewportHeight="32"android:viewportWidth="32"><pathandroid:fillColor="#8000"android:pathData="M20.5,9.5c-1.955,0,-3.83,1.268,-4.5,3c-0.67,-1.732,-2.547,-3,-4.5,-3C8.957,9.5,7,11.432,7,14c0,3.53,3.793,6.257,9,11.5c5.207,-5.242,9,-7.97,9,-11.5C25,11.432,23.043,9.5,20.5,9.5z" />
</vector>

flight/src/main/res/drawable/battery.xml文件

<vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="100dp"android:height="100dp"android:viewportHeight="24.0"android:viewportWidth="24.0"><groupandroid:name="rotationGroup"android:pivotX="10.0"android:pivotY="10.0"android:rotation="15.0"><pathandroid:name="vect"android:fillAlpha=".3"android:fillColor="#FF000000"android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33V9h4.93L13,7v2h4V5.33C17,4.6 16.4,4 15.67,4z" /><pathandroid:name="draw"android:fillColor="#FF000000"android:pathData="M13,12.5h2L11,20v-5.5H9L11.93,9H7v11.67C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V9h-4v3.5z" /></group>
</vector>

VectorDrawable引用
flight/src/main/res/layout/activity_flight.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-autoxmlns:tools="http://schemas.android.com/tools"... ... tools:context="com.qunar.flight.FlightActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="flight" /><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"app:srcCompat="@drawable/heart"/><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"app:srcCompat="@drawable/battery"/>
</LinearLayout>

注意:如果你不使用support library兼容,使用生成png图片,那么不用添加命名空间,采用android:src属性即可;
运行结果

三、AnimatedVectorDrawable实践
1.AnimatedVectorDrawable简介

AnimatedVectorDrawable向矢量图添加动画属性。你可以分三个文件或者一个Drawable的XML文件定义矢量图动画。为了更好的理解,让我们来看看这两种方式:多个XML文件和单个XML文件;
2.多个XML文件
使用这种方式,你需要定义三个单独的XML文件:
  一个VectorDrawable XML文件;
  一个AnimatedVectorDrawable XML文件定义了目标VectorDrawable,动画用于目标path和group,属性和动画定义为ObjectAnimator对象或者AnimatorSet对象;
  一个动画XML文件;
AnimatedVectorDrawable多XML文件定义
首先我们想将哪个矢量图片动起来(vd.xml),该图片要运行什么样的动画(rotation.xml和path_morph.xml),将矢量图和动画结合(avd.xml);
flight/src/main/drawable/vd.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"android:height="64dp"android:width="64dp"android:viewportHeight="600"android:viewportWidth="600" ><groupandroid:name="rotationGroup"android:pivotX="300.0"android:pivotY="300.0"android:rotation="45.0" ><pathandroid:name="vectorPath"android:fillColor="#000000"android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /></group>
</vector>

flight/src/main/res/anim/rotation.xml

<set xmlns:android="http://schemas.android.com/apk/res/android"><objectAnimatorandroid:duration="6000"android:propertyName="rotation"android:valueFrom="0"android:valueTo="360" />
</set>

flight/src/main/res/anim/path_morph.xml

<set xmlns:android="http://schemas.android.com/apk/res/android"><objectAnimatorandroid:duration="3000"android:propertyName="pathData"android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"android:valueType="pathType"/>
</set>

flight/src/main/drawable/avd.xml

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"android:drawable="@drawable/vd" ><targetandroid:name="rotationGroup"android:animation="@anim/rotation" /><targetandroid:name="vectorPath"android:animation="@anim/path_morph" />
</animated-vector>

AnimatedVectorDrawable引用
接下来,我们就可以在视图中应用该适量图片动画,运行动画;
flight/src/main/layout/activity_flight.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"... ... tools:context="com.qunar.flight.FlightActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="flight" />... ... <ImageViewandroid:id="@+id/imageview1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/avd"/>
</LinearLayout>

flight/src/main/java/com/qunar/flight/FlightActivity.java

public class FlightActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_flight);ImageView imageView = (ImageView) findViewById(R.id.imageview1);Drawable drawable = imageView.getDrawable();if (drawable instanceof Animatable){((Animatable) drawable).start();}}
}

运行效果

3.单个XML文件
使用这种方式,你可以合并相关的XML文件到一个使用XML Bundle格式的XML文件中。在构建app的时候,aapt tag会创建单独的资源并且在矢量动画引用它们。这种方式要求Build Tools 24或者更高,并且输出是向后兼容的;
AnimatedVectorDrawable单文件定义
flight/src/main/drawable/single_avd.xml

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" ><aapt:attr name="android:drawable"><vectorandroid:height="64dp"android:width="64dp"android:viewportHeight="600"android:viewportWidth="600" ><groupandroid:name="rotationGroup"android:pivotX="300.0"android:pivotY="300.0"android:rotation="45.0" ><pathandroid:name="v"android:fillColor="#000000"android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /></group></vector></aapt:attr><target android:name="rotationGroup"> *<aapt:attr name="android:animation"><objectAnimatorandroid:duration="6000"android:propertyName="rotation"android:valueFrom="0"android:valueTo="360" /></aapt:attr></target><target android:name="v" ><aapt:attr name="android:animation"><set><objectAnimatorandroid:duration="3000"android:propertyName="pathData"android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z"android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"android:valueType="pathType"/></set></aapt:attr></target></animated-vector>

注意:为了优化重绘性能,每个VectorDrawable对象创建了Bitmap缓存。因此,引用相同的VectorDrawable意味着共享相同的Btimap缓存。如果这些引用大小上不一致,Bitmap将会在大小每次变化的时候重建和重绘。换句话说,如果VectorDrawable使用了不同的大小,为每个大小创建VectorDrawable会效率更高;

四、代码库

QProject:https://github.com/Pengchengxiang/QProject  分支:ui/vectordrawable

新技术,新未来!欢迎大家关注“1024工场”微信服务号,时刻关注我们的最新的技术讯息!(甭客气!尽情的扫描或者长按!)

Android UI:使用矢量图,抛弃PNG相关推荐

  1. Android 开发 VectorDrawable 矢量图 (三)矢量图动画

    Android 开发 VectorDrawable 矢量图 (三)矢量图动画 简介--矢量动画2种方式与流程 矢量动画有一些不一样的细节,这里需要提前了解,否则容易在后续使用的时候困惑. 1.使用gr ...

  2. SVG - 在Android中使用矢量图全攻略

    概念 什么是矢量图,SVG SVG全称:可伸缩矢量图形 (Scalable Vector Graphics) SVG 用来定义用于网络的基于矢量的图形 SVG 使用 XML 格式定义图形 SVG 图像 ...

  3. 自己制作 Android Vector Asset 矢量图

    从5.0(API等级21)开始,Android开始支持矢量图了.关于什么是矢量图以及矢量图有什么优缺点不在本文的涉及范围之内,具体可以参考矢量图百科.不过这里要提一下它的优点: 保存最少的信息,文件大 ...

  4. Android矢量图动画特效,Android使用SVG矢量图打造酷炫动画效果

    一个真正Android使用SVG矢量图打造酷炫动效往往让人虎躯一震,话不多说,咱们先看看效果: 这个效果我们需要考虑以下几个问题: 1. 这是图片还是文字: 2. 如果是图片该如何拿到图形的边沿线坐标 ...

  5. android MD之矢量图和动画篇

    1 简介 Android 5.0 中增加了对SVG 矢量图形的支持,利用svg我们能做以下东西: 1.炫酷的动画效果 2.Vector图像可以自动进行适配,不失真 3.同样一张图,用Vector来实现 ...

  6. 【笔记】Android 使用自定义矢量图,ps文件转矢量图

    不用再手撸svg代码了 可以试试ps文件转svg代码 首先去ps编辑图片文件 将所有图层合并为一图层 按Ctrl+点击图层,获取图层选取 去路径-将选取生成路径 1.回到图层 2.点击钢笔工具 3.点 ...

  7. android 矢量图 背景 ui,Android:使用矢量图图标库+9-patch图进行UI设计

    矢量图UI + 9-Patch适配 首先矢量图网站: https://www.iconfont.cn/ 里面提供了丰富的矢量图标,供开发者使用 效果: 矢量图库 下载图标 + 导入到Android S ...

  8. Android 关于SVG矢量图支持

    原文出处:微信,脉脉不得语的安卓开发技术周报 47期推荐 资源矢量化 "清晰"和"体积"的矛盾与麻烦 面对android的各种dpi某事,想要所有设备上的图片都 ...

  9. Android使用SVG矢量图打造酷炫动效!

    一个真正酷炫的动效往往让人虎躯一震,话不多说,咱们先瞅瞅效果: 如果你想看 GAStudio Github主页,请戳这里: 如果你想看 GAStudio更多技术文章,请戳这里: QQ技术交流群:277 ...

  10. android 矢量图 开源,Android 使用 SVG 矢量图

    android svg矢量图 可能包含的操作有: SVG图还包括改变颜色,透明度,大小,矩阵操作(平移.旋转.缩放),selector, (图标,背景,按钮),动画,等 setTint(int Col ...

最新文章

  1. Java中的访问控制权限
  2. LeetCode---------Longest Substring Without Repeating Characters解法
  3. 升级Xcode7.3 iOS9.3后,unity转C++代码出现 2 errors
  4. python画图代码彩虹-用python画一颗彩虹色爱心送给女朋友!!!
  5. 编程之美-高效率安排见面会的方法整理
  6. RocketMQ(一):Linux安装RocketMQ和常用命令
  7. JSP的<c:foreach/>标签只输出一次标签体内容的坑
  8. python爬虫验证码的识别_Python爬虫识别验证码
  9. 学做三件事、三句话、三乐、三不要
  10. swap函数_C++ vector成员函数实现[持续更新]
  11. Android 中的拿来主义(编译,反编译,AXMLPrinter2,smali,baksmali)!
  12. php连接mysql地址_PHP连接mysql
  13. HTML5开发能不能取代原生开发?
  14. SQLServer数据库中截取字符串的常用方法
  15. 高一计算机教学,高一信息技术教学计划参考
  16. 华硕笔记本系统重装之后需要输入用户名和计算机名称是怎么回事,华硕笔记本电脑重装系统【方法详解】...
  17. drm单个framebuffer显示
  18. [解决]通常每个套接字地址只允许使用一次
  19. 无人机快速三维建模平台
  20. VMware-workstation-full-10.0.2中英文切换

热门文章

  1. Android开发好用的依赖库
  2. unity3d kinect体感互动解决方案——2D体感换装
  3. 关于磁力计偏置值的标定实践
  4. 南大计算机系2014保研,【公示】2013年南京大学计算机系保研名单公示(院系初步推免)...
  5. 第一款无代码应用平台搭建的设备管理系统
  6. TRNSYS与MATLAB联合仿真
  7. 第3章-数理知识基础 -> 代数图论
  8. Inpaint 强大的去水印、改图软体,轻鬆把不要的物件从相片中移除
  9. 简单介绍在线OTA几款平台
  10. Msfconsole的基本使用