VectorDrawable矢量图
AndroidL中有一个非常好的新特性是VectorDrawable以及相关的一些类,他们为我们提供了添加复杂矢量图形的强大功能,同时也提供了动画显示这些图形的方法,不用写很多代码就可以实现非常复杂的动画。矢量图形的好处是放大不会失真,可以适应不同分辨率的屏幕。简单的来说,矢量图形就是使用几个形状的方式来描述一个图像元素。矢量图形非常适合于与设备无关的简单或者合成的制图或者不需要实现真实感的场合。而位图(Bitmap ),则完全相反,位图是定义每一个像素点的颜色来显示一张图片,它适合显示一张真实的照片。矢量图形的一大好处是它的渲染是在运行时开始的,因此它可以自适应不同的屏幕。由于矢量图其实保存的只是描述几何图形的文本,因此它只占用非常少的空间。Android 默认的小机器人图标svg格式的2265字节,但是如果我们将它转换成500 x 500的bitmap文件,保存成png格式,则有13272 字节。并且它可以自动伸缩为任意大小的图片,而位图就需要使用多张才能达到不同分辨率的效果。
svg的源码 (https://www.w3.org/TR/SVG/paths.html)
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve">
<g id="max_width__x2F__height" display="none">
<path display="inline" d="M499.001,1v498H1V1H499.001 M500.001,0H0v500h500.001V0L500.001,0z"/>
</g>
<g id="androd">
<path fill="#9FBF3B" d="M301.314,83.298l20.159-29.272c1.197-1.74,0.899-4.024-0.666-5.104c-1.563-1.074-3.805-0.543-4.993,1.199L294.863,80.53c-13.807-5.439-29.139-8.47-45.299-8.47c-16.16,0-31.496,3.028-45.302,8.47l-20.948-30.41c-1.201-1.74-3.439-2.273-5.003-1.199c-1.564,1.077-1.861,3.362-0.664,5.104l20.166,29.272c-32.063,14.916-54.548,43.26-57.413,76.34h218.316C355.861,126.557,333.375,98.214,301.314,83.298"/>
<path fill="#FFFFFF" d="M203.956,129.438c-6.673,0-12.08-5.407-12.08-12.079c0-6.671,5.404-12.08,12.08-12.08c6.668,0,12.073,5.407,12.073,12.08C216.03,124.03,210.624,129.438,203.956,129.438"/>
<path fill="#FFFFFF" d="M295.161,129.438c-6.668,0-12.074-5.407-12.074-12.079c0-6.673,5.406-12.08,12.074-12.08c6.675,0,12.079,5.409,12.079,12.08C307.24,124.03,301.834,129.438,295.161,129.438"/>
<path fill="#9FBF3B" d="M126.383,297.598c0,13.45-10.904,24.354-24.355,24.354l0,0c-13.45,0-24.354-10.904-24.354-24.354V199.09c0-13.45,10.904-24.354,24.354-24.354l0,0c13.451,0,24.355,10.904,24.355,24.354V297.598z"/>
<path fill="#9FBF3B" d="M140.396,175.489v177.915c0,10.566,8.566,19.133,19.135,19.133h22.633v54.744
c0,13.451,10.903,24.354,24.354,24.354c13.451,0,24.355-10.903,24.355-24.354v-54.744h37.371v54.744c0,13.451,10.902,24.354,24.354,24.354s24.354-10.903,24.354-24.354v-54.744h22.633c10.569,0,19.137-8.562,19.137-19.133V175.489
H140.396z"/>
<path fill="#9FBF3B" d="M372.734,297.598c0,13.45,10.903,24.354,24.354,24.354l0,0c13.45,0,24.354-10.904,24.354-24.354V199.09c0-13.45-10.904-24.354-24.354-24.354l0,0c-13.451,0-24.354,10.904-24.354,24.354V297.598z"/>
</g>
</svg>
矢量图详细介绍
1、支持的指令:
M = moveto 相当于 android Path 里的moveTo(),用于移动起始点
L = lineto 相当于 android Path 里的lineTo(),用于画线
H = horizontal lineto 用于画水平线
V = vertical lineto 用于画竖直线
C = curveto 相当于cubicTo(),三次贝塞尔曲线
S = smooth curveto 同样三次贝塞尔曲线,更平滑
Q = quadratic Belzier curve quadTo(),二次贝塞尔曲线
T = smooth quadratic Belzier curveto 同样二次贝塞尔曲线,更平滑
A = elliptical Arc 相当于arcTo(),用于画弧
Z = closepath 相当于closeTo(),关闭path
2、使用原则:
①坐标轴为以(0,0)为中心,X轴水平向右,Y轴水平向下。
②所有指令大小写均可。大写绝对定位,参照全局坐标系;小写相对定位,参照父容器坐标系
③指令和数据间的空格可以省略
④同一指令出现多次可以只用一个
注意,’M’处理时,只是移动了画笔, 没有画任何东西。 它也可以在后面给出上同时绘制不连续线。
3、详细指令分析
3.1、L H V指令
绘制直线的指令是“L”,从当前点划线到给定点。 “L”之后的参数是一个点坐标,如“L 200 400”。 如果画水平线或垂直线,可以使用“H”和“V”指令,后面的参数是x(H指令)或y坐标(V指令)。
M 起点X,起点Y L(直线)终点X,终点Y H(水平线)终点X V(垂直线)终点Y
如:M 10,20 L 80,50 M 10,20 V 50 M 10,20 H 90
3.2、A指令
允许不闭合。可以想像成是椭圆的某一段,共七个参数
A RX,RY,XROTATION,FLAG1,FLAG2,X,Y
RX,RY指所在椭圆的半轴大小
XROTATION指椭圆的X轴与水平方向顺时针方向夹角,可以想像成一个水平 的椭圆绕中心点顺时针旋转XROTATION的角度。
FLAG1只有两个值,1表示大角度弧线,0为小角度弧线。
FLAG2只有两个值,确定从起点至终点的方向,1为顺时针,0为逆时针
X,Y为终点坐标。
M 20,50 A 30,30,0,1 0 80,50 这个就是画一个下半圆。
3.3 C指令 三次贝塞尔曲线。相关博客很多,不在追述。
我们把刚才svg的源码整理成Android的VectorDrawable:
创建一个androidvector.xml内容如下:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"android:viewportWidth="500"android:viewportHeight="500"android:width="500px"android:height="500px"><group android:name="android"><group android:name=" head _android"><path
android:name="head"android:fillColor="#9FBF3B" android:pathData="M301.314,83.298l20.159-29.272c1.197-1.74,0.899-4.024-0.666-5.104c-1.563-1.074-3.805-0.543-4.993,1.199L294.863,80.53c-13.807-5.439-29.139-8.47-45.299-8.47c-16.16,0-31.496,3.028-45.302,8.47l-20.948-30.41c-1.201-1.74-3.439-2.273-5.003-1.199c-1.564,1.077-1.861,3.362-0.664,5.104l20.166,29.272c-32.063,14.916-54.548,43.26-57.413,76.34h218.316C355.861,126.557,333.375,98.214,301.314,83.298" /></group><group android:name="left_eye _android"><path
android:name="left_eye"android:fillColor="#FFFFFF"android:pathData="M203.956,129.438c-6.673,0-12.08-5.407-12.08-12.079c0-6.671,5.404-12.08,12.08-12.08c6.668,0,12.073,5.407,12.073,12.08C216.03,124.03,210.624,129.438,203.956,129.438" /></group><group android:name=" right_eye _android"><path
android:name="right_eye"android:fillColor="#FFFFFF"android:pathData="M295.161,129.438c-6.668,0-12.074-5.407-12.074-12.079c0-6.673,5.406-12.08,12.074-12.08c6.675,0,12.079,5.409,12.079,12.08C307.24,124.03,301.834,129.438,295.161,129.438" /></group><group android:name=" left_arm _android"><path
android:name="left_arm"android:fillColor="#9FBF3B"android:pathData="M126.383,297.598c0,13.45-10.904,24.354-24.355,24.354l0,0c-13.45,0-24.354-10.904-24.354-24.354V199.09c0-13.45,10.904-24.354,24.354-24.354l0,0c13.451,0,24.355,10.904,24.355,24.354V297.598z" /></group><group android:name=" body _android"><path
android:name="body"android:fillColor="#9FBF3B"android:pathData="M140.396,175.489v177.915c0,10.566,8.566,19.133,19.135,19.133h22.633v54.744c0,13.451,10.903,24.354,24.354,24.354c13.451,0,24.355-10.903,24.355-24.354v-54.744h37.371v54.744c0,13.451,10.902,24.354,24.354,24.354s24.354-10.903,24.354-24.354v-54.744h22.633c10.569,0,19.137-8.562,19.137-19.133V175.489H140.396z" /></group><group android:name=" right_arm _android"><path
android:name="right_arm"android:fillColor="#9FBF3B"android:pathData="M372.734,297.598c0,13.45,10.903,24.354,24.354,24.354l0,0c13.45,0,24.354-10.904,24.354-24.354V199.09c0-13.45-10.904-24.354-24.354-24.354l0,0c-13.451,0-24.354,10.904-24.354,24.354V297.598z" /></group></group>
</vector>
虽然有对path 规则的绘制教程,但是要创造出现有安卓中各种图标的效果是很难的,要让VectorDrawable有实际价值,肯定不能让开发者去想办法实现这些图形的绘制。
VectorDrawable还可以用来制作动画,动态Vector才是Android Vector Drawable的精髓所在,那么我们就有了个新的名词叫AnimatedVectorDrawable,AnimatedVectorDrawable可以让VectorDrawable动起来,AnimatedVectorDrawable通过改变VectorDrawable的属性来让VectorDrawable呈现动画效果,其实现实际上是试用了属性动画。
通常定义一个AnimatedVectorDrawable需要以下三个xml文件:
1.vector drawable本身:res/drawable/中定义一个有元素的xml文件,参考上面对VectorDrawable的定义。
2.vector drawable的动画文件(Animated vector drawable):res/drawable/中定义一个有元素的xml文件。
3.一个或者多个属性动画文件:res/drawable/中定义一个有元素的xml文件。
Animated vector drawable可以让和元素的属性动态变化。定义一组path或者子group,而元素定义需要绘制的路径。当你想让VectorDrawable呈现动画效果,在定义VectorDrawable的时候需要为group和path的android:name属性设置一个唯一的名字,以便在Animated vector drawable中找到它们。
接下来我们就让小机器人跳舞。
创建动画shrug.xml文件
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><objectAnimator
android:propertyName="translateY"android:valueType="floatType"android:valueFrom="0"android:valueTo="-10"android:repeatMode="reverse"android:repeatCount="infinite"android:duration="250" />
</set>
创建一个android_anim.xml文件
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"android:drawable="@drawable/androidvector"><target
android:animation="@anim/shrug"android:name=" left_arm _android " /><target
android:animation="@anim/shrug"android:name=" right_arm _android " />
</animated-vector>
如果运行现在的代码,我们只能看到静态的图片。这是因为我们需要手动调用播放动画。
ImageView androidImageView = (ImageView) findViewById(R.id.android);Drawable drawable = androidImageView.getDrawable();if (drawable instanceof Animatable) {((Animatable) drawable).start();}
接下来我们再看一个例子:
viewportWidth:定义图像被划分的比例大小,例如例子中的500,即把500px大小的图像划分成500份,后面Path标签中的坐标,就全部使用的是这里划分后的坐标系统。
star_img.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"android:viewportHeight="500"android:viewportWidth="500"android:width="500px"android:height="500px"><group android:scaleX="5.0" android:scaleY="5.0"><path
android:name="star"android:strokeColor="#FF b64f9e"android:strokeWidth="2"android:pathData="
M 50.0,90.0 L 82.9193546357,27.2774101308 L 12.5993502926,35.8158045183 L 59.5726265715,88.837672697 L76.5249063296,20.0595700732 L 10.2916450361,45.1785327898
L 68.5889268818,85.4182410261 L 68.5889268818,14.5817589739 L10.2916450361,54.8214672102
L 76.5249063296,79.9404299268 L 59.5726265715,11.162327303 L12.5993502926,64.1841954817
L 82.9193546357,72.7225898692 L 50.0,10.0 L 17.0806453643,72.7225898692
L 87.4006497074,64.1841954817 L 40.4273734285,11.162327303 L23.4750936704,79.9404299268
L 89.7083549639,54.8214672102 L 31.4110731182,14.5817589739 L31.4110731182,85.4182410261
L 89.7083549639,45.1785327898 L 23.4750936704,20.0595700732 L40.4273734285,88.837672697
L 87.4006497074,35.8158045183 L 17.0806453643,27.2774101308 L50.0,90.0Z" /></group>
</vector>path.xml<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:ordering="together"android:duration="2000"android:repeatMode="reverse"android:repeatCount="1">
<objectAnimator android:propertyName="trimPathEnd" //这里也可以用"trimPathStart"android:valueFrom="0"android:valueTo="1"android:duration="2000"android:valueType="floatType"android:interpolator="@android:interpolator/linear"></objectAnimator>
<objectAnimator
android:duration="2000"android:propertyName="strokeColor"android:valueFrom=" #ff4f65b6"android:valueTo="#ff 6cb64f "
/>
</set>
star_anim.xml:
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"android:drawable="@drawable/star_img"><target
android:animation="@animator/path"android:name="star" /></animated-vector>
从一张图片过渡到另外一张图片:
square.xml:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"android:viewportWidth="500"android:viewportHeight="500"android:width="500px"android:height="500px"><path android:name="square"android:fillColor="#ff 00ff00"android:pathData="M100,100 L400,100 L400,400 L100,400 z" /></vector>animated_square.xml:<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/square"><target
android:animation="@animator/to_triangle"android:name="square" />
</animated-vector>
现在到了关键部分-Animator自身。我们要实现将正方形向三角形动画过度。实现的方法是将开始值和结束值定义成两个不同的path。起始path是正方形(上面已经定义),结束path是三角形。
必须记住起始和结束path的参数个数要相等,同时这些参数的类型要匹配。我们的正方形path是由move命令(M开头表示move)开始,然后是3个line命令,和最后的关闭命令组成的,因此三角形也必须符合这个模式。但是三角形只需要三条线,而正方形是四条线,因此我们需要一点技巧。我们将正方形上边的中点作为顶点,并且在这个点绘制两次。
(M250,100L250,100L400,400L100,400z)
to_triangle.xml:
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"android:duration="1000"android:interpolator="@android:interpolator/decelerate_cubic"android:repeatMode="reverse"android:repeatCount="1"android:propertyName="pathData"android:valueType="pathType"android:valueFrom="M100,100L400,100L400,400L100,400z"android:valueTo="M250,100L250,100L400,400L100,400z" />
pathInterpolator路径差值器:
<pathInterpolator
xmlns:android="http://schemas.android.com/apk/res/android"android:pathData="M 0.0,0.0 c 0.33333333,0.0 0.0,1.0 1.0,1.0" />
*android studio也提供了丰富的图片资源,可以右键module,new->vector Asset选
最后我在网上找的一个开源的Vector的动画Demo库https://github.com/xuyisheng/VectorDemo 有兴趣的可以下载下来研究一下
VectorDrawable矢量图相关推荐
- Android开发之将Android SVG 转 VectorDrawable矢量图的方法
Android SVG to VectorDrawable介绍两种方法如下 方法一 使用在线的三方网站即可我推荐两个: Android SVG to VectorDrawable Android SV ...
- Android 开发 VectorDrawable 矢量图 (三)矢量图动画
Android 开发 VectorDrawable 矢量图 (三)矢量图动画 简介--矢量动画2种方式与流程 矢量动画有一些不一样的细节,这里需要提前了解,否则容易在后续使用的时候困惑. 1.使用gr ...
- Android VectorDrawable 矢量图+属性动画 使用总结
代码已经同步到GitHub 然后看一下效果图: 前两个图标是让android的组件使用VectorDrawable 后面的是动画效果 后面会详细介绍. 什么是VectorDrawable Vector ...
- Android矢量图vector的制作
Android矢量图vector的制作 一:Android 图片适配的发展史 在Android的发展历程中,由于设备碎片化的原故,谷歌在app中图标的适配上做出一步又一步的改进,大体有这么几个阶段: ...
- android矢量图之VectorDrawable ,自由又方便的填充色彩
背景 偶然间,在极客学院看到一个视频:VectorDrawable 原理和使用.很惭愧,以前还真没用到,于是,今天就来学习下.2014年6月26日的I/O 2014开发者大会上谷歌正式推出了Andro ...
- 矢量图VectorDrawable轻松实现箭头左右移动动画
最近在学习利用矢量图VectorDrawable实现动画,发现矢量图也很强大,很多动画效果都可以简单实现,下面就是其中一个简单箭头左右移动的动画. 下面开始实现这个动画效果 1. 在res文件夹下创建 ...
- android+矢量图+插件,如何玩转Android矢量图VectorDrawable
从5.0(api等级21)开始,android开始支持矢量图了.关于什么是矢量图以及矢量图有什么优缺点不在本文的涉及范围之内,具体可以参考矢量图百科.不过这里要提一下它的优点: 保存最少的信息,文件大 ...
- android 颜色填充工具,Android矢量图之VectorDrawable类自由填充色彩
2014年6月26日的I/O 2014开发者大会上谷歌正式推出了Android L,它带来了全新的设计语言Material Design,新的API也提供了这个类VectorDrawable .也就是 ...
- Android使用矢量图(SVG, VectorDrawable)实践篇
供自己学习的笔记 原文链接:http://www.jianshu.com/p/0555b8c1d26a 前言 本文是以读者对SVG有一定了解为前提的,否则请先百(谷)度(歌)了解下. 实践都是从坑里爬 ...
最新文章
- 英特尔凌动处理器_曾押宝英特尔凌动CPU,华硕手机如今活得如何了?
- 【DP】饥饿的WZK(jzoj 1998)
- 单元测试 问题描述_单元测试技巧:创建描述性测试
- linux php木马下载,Linux shell快速查找PHP木马
- 仿ios桌面vivo_vivo全新OriginOS细节曝光:系统UI大变样
- Python实现分析pdf或者Word形式简历,并且保存到Excel中
- mysql断了导致rabbitmq挂了,rabbitmq 消费线程无故中断连接
- Oracle 常用脚本1
- 张宇八套卷(四)复盘
- IDEA 格式化代码快捷键冲突解决
- postman实现接口请求
- RGB色彩之间的过渡参考
- 腾讯2020校园招聘-后台
- 04【前端工程化初探】Jenkines+GitLab+Tomcat流水线配置部署React应用
- Spring boot集成Redis实现sessions共享时,sessions过期时间问题分析
- idea智能提示设置和修改提示快捷键
- 计算机毕业设计_基于SSM的医院预约挂号系统设计与实现
- redis切换db方法
- 在cadence中使用VerilogA
- 百度输入法下载|百度拼音输入法下载