ps如何制作矢量图玩转Android矢量图VectorDrawable

Android5.0之后 VectorDrawable实现超炫酷动画效果 - 简书
Android5.0之后 VectorDrawable实现超炫酷动画效果
标签介绍:
&vector&, &group&, &clip-path&,&animated-vector& 项目中还是用到了一些动画的标签,这里就不做展示了
pathandroid:name 定义该 path 的名字,这样在其他地方可以通过名字来引用这个路径android:pathData 和 SVG 中 d 元素一样的路径信息。android:fillColor 定义填充路径的颜色,如果没有定义则不填充路径android:strokeColor 定义如何绘制路径边框,如果没有定义则不显示边框android:strokeWidth 定义路径边框的粗细尺寸android:strokeAlpha 定义路径边框的透明度android:fillAlpha 定义填充路径颜色的透明度android:trimPathStart 从路径起始位置截断路径的比率,取值范围从 0 到1android:trimPathEnd 从路径结束位置截断路径的比率,取值范围从 0 到1android:trimPathOffset 设置路径截取的范围,取值范围从 0 到1android:strokeLineCap 设置路径线帽的形状,取值为 butt, round, square.android:strokeLineJoin 设置路径交界处的连接方式,取值为 miter,round,bevel.android:strokeMiterLimit 设置斜角的上限文
vector:定义这个矢量图android:name 定义该drawable的名字android:width 定义该 drawable 的内部(intrinsic)宽度,支持所有 Android 系统支持的尺寸,通常使用 dpandroid:height 定义该 drawable 的内部(intrinsic)高度,支持所有 Android 系统支持的尺寸,通常使用 dpandroid:viewportWidth 定义矢量图视图的宽度,视图就是矢量图 path 路径数据所绘制的虚拟画布android:viewportHeight 定义矢量图视图的高度,视图就是矢量图 path 路径数据所绘制的虚拟画布android:tint 定义该 drawable 的 tint 颜色。默认是没有 tint 颜色的android:tintMode 定义 tint 颜色的 Porter-Duff blending 模式,默认值为 src_inandroid:autoMirrored 设置当系统为 RTL (right-to-left) 布局的时候,是否自动镜像该图片。android:alpha 该图片的透明度属性
首先创建一个vectorDrawable
先展示一下效果图
登录界面的vectorDrawable
现在看上去还是没一点鸟用哈,也没什么特点,下一篇博客将给你惊喜,这里就不管它了
注意:这里宽高(width和height的比例及viewportHeight和viewportWidth比例)的比例很重要,这个比例必须和布局文件中宽高比例一直,比如布局文件中的宽是300dp,高是100dp,那么宽高的比例就是3:1,所以在vector中的宽高比例就是3:1 不要怪我啰嗦,因为你如果不对应,导致的直接结果就是显示后的图形是拉伸或是压缩的,然后你可能会想。我改一下就好了,那恭喜你你成功给自己挖了一个大坑,全是计算
&vector xmlns:android="/apk/res/android"
android:width="75dp"
android:height="25dp"
android:viewportHeight="40"
android:viewportWidth="120"&
android:name="firstHLine"
android:pathData="M 0,20 l 90,0"
android:strokeAlpha="0.8"
android:strokeColor="@android:color/holo_red_dark"
android:strokeWidth="0.5" /&
android:name="circleTop"
android:pathData="M 90,20
A 9,9 0,1,0 81,11"
android:strokeAlpha="0.8"
android:strokeColor="@android:color/holo_red_dark"
android:strokeWidth="0.5" /&
android:name="true"
android:pathData="M 81,11 l 4,6 l 10,-8"
android:strokeAlpha="0.8"
android:strokeColor="@android:color/holo_red_dark"
android:strokeLineCap="round"
android:strokeWidth="0.5" /&
android:name="circleBouttom"
android:pathData="
A 9,9 0,1,1 90,38"
android:strokeAlpha="0.8"
android:strokeColor="@android:color/holo_red_dark"
android:strokeWidth="0.5" /&
android:name="secondHLine"
android:pathData="M 0,38 l 90,0"
android:strokeAlpha="0.8"
android:strokeColor="@android:color/holo_red_dark"
android:strokeWidth="0.5" /&
没错我第一次看到vector的时候也是一脸懵逼,这t m是啥呀,全是字母加数字,那就具体来解释一下吧
vectorDrawable支持的指令:
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):画圆弧。分别对应: x轴半径,y轴半径,x轴偏移量,弧度(0代表取小弧度,1代表取大弧度) ,方向(0取逆时针,1为顺时针),目标X坐标,目标y坐标。(当rx=ry时就是一个圆,但是终点坐标要对哈)
Z = closepath():关闭路径
注意:这里字母大写和字母小写也是有讲究的,大写代表当前空间的绝对位置,小写代表相对位置,比如M(10,10)指的是移动到当前空间的x=10,y= 10这个位置(绝对位置),m(10,10)则指的是从当前点向右10个单位位置的点,并从当前点向下10个单位位置的点(相对位置)这里提一下至于数字中间用逗号间隔,还是用空格来隔开都没关系,根据个人喜好
测试大写和小写分别对应的效果,代码如下
&vector xmlns:android="/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="100"
android:viewportWidth="100"&
android:pathData="M 0,10,L 100,10"
android:strokeColor="@android:color/holo_red_light"
android:strokeWidth="2" /&
android:pathData="M 0,40,l 100,40"
android:strokeColor="@android:color/holo_blue_light"
android:strokeWidth="2" /&
android:pathData="M 0,80,L 100,80"
android:strokeColor="@android:color/white"
android:strokeWidth="2" /&
光文字,干燥,来张图片,醒醒脑
上面路径对应的图
是不是一下感觉就懂了大小写的区别了
接下来就来画一些基本的图形(直线就不画了,上面有了),感受下vectorDrawable
先来画个圆吧
&vector xmlns:android="/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"&
android:name="circle"
android:pathData="
M12,12//定位到当前空间的中心
m-10,0 //从当前点向左移动10个单位
a10,10 0 1,1 20,0//在当前点绘制一个以上面的m点为起点半径为10,终点是(20,0),注意小写是相对位置
a10,10 0 1,1 -20,0"//与上面同理
android:strokeColor="@color/colorPrimary"
android:strokeWidth="1" /&
&!--你可能会想为什么要画两个半圆而不是一个整圆,我只能说你可以试试--&
再来个难度高点的
&vector xmlns:android="/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="200"
android:viewportWidth="200"&
android:fillColor="@color/colorAccent"
android:pathData="
h180//从当前点向右一条直线,绘制180个单位
q10,0 10,10//这就是贝赛曲线
v180//从当前点向下一条直线,绘制180个单位
q0,10 -10,10
q-10,0 -10,-10
q 0,-10 10,-10
a 30,40 -60,1,0 -60 ,10
c 20,20 40,40 60,60
c 20,-20 40,-40 60,-60//三次贝赛曲线
a 30,40 60,1,0 -60 ,-10"
android:strokeColor="@color/colorPrimary" /&
贝赛曲线绘制很简单的,但是实际用到比较少,我暂时就不做讲解了,下一篇博客的文章末尾我会给出一些学习的链接h和v方法是太简单,读者一试便知,就不绘制了
奔跑的蜗牛VectorDrawable
Android L开始提供了新的API VectorDrawable 可以使用SVG类型的资源,也就是矢量图。先来一个例子吧。
[html] view plain copy
&?xml version=&1.
VectorDrawable
L开始提供了新的API VectorDrawable 可以使用SVG类型的资源,也就是矢量图。先来一个例子吧。
上面的代码绘制出来的就是这么一个图像,控制显示心形的就是上面path这个标签,一个path代表一个元素,绘制的内容是pathData下的一长串字符,里面是SVG绘制的一系列命令,提供moveTo、lineTo、close等操作。那么接下来说说这些M,c.l标签吧。
M: move to 移动绘制点
L:line to 直线
Z:close 闭合
C:cubic bezier 三次贝塞尔曲线
Q:quatratic bezier 二次贝塞尔曲线
A:ellipse 圆弧
M (x y) 移动到x,y
L (x y) 直线连到x,y,还有简化命令H(x) 水平连接、V(y)垂直连接
Z,没有参数,连接起点和终点
C(x1 y1 x2 y2 x y),控制点x1,y1 x2,y2,终点x,y
Q(x1 y1 x y),控制点x1,y1,终点x,y
A(rx ry x-axis-rotation large-arc-flag sweep-flag x y)
rx ry 椭圆半径
x-axis-rotation x轴旋转角度
large-arc-flag 为0时表示取小弧度,1时取大弧度
sweep-flag 0取逆时针方向,1取顺时针方向
有个图解:
有了这些,我们可以随意的定制矢量图了,来一发,我们定义一个三角形
我们说说这些常用标签的含义:
path 元素里面的 pathData 就是矢量图的路径数据,除此之外还可以设置其他属性。 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.注: 当strokeLineJoin设置为 “miter” 的时候, 绘制两条线段以锐角相交的时候,所得的斜面可能相当长。当斜面太长,就会变得不协调。strokeMiterLimit 属性为斜面的长度设置一个上限。这个属性表示斜面长度和线条长度的比值。默认是 10,意味着一个斜面的长度不应该超过线条宽度的 10 倍。如果斜面达到这个长度,它就变成斜角了。当 strokeLineJoin 为 “round” 或 “bevel” 的时候,这个属性无效。
根元素 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 颜色的
模式,默认值为 src_in
android:autoMirrored 设置当系统为 RTL (right-to-left) 布局的时候,是否自动镜像该图片。比如 阿拉伯语。
android:alpha 该图片的透明度属性
有时候我们需要对几个路径一起处理,这样就可以使用 group 元素来把多个 path 放到一起。 group 支持的属性如下:
android:name 定义 group 的名字
android:rotation 定义该 group 的路径旋转多少度
android:pivotX 定义缩放和旋转该 group 时候的 X 参考点。该值相对于 vector 的 viewport 值来指定的。
android:pivotY 定义缩放和旋转该 group 时候的 Y 参考点。该值相对于 vector 的 viewport 值来指定的。
android:scaleX 定义 X 轴的缩放倍数
android:scaleY 定义 Y 轴的缩放倍数
android:translateX 定义移动 X 轴的位移。相对于 vector 的 viewport 值来指定的。
android:translateY 定义移动 Y 轴的位移。相对于 vector 的 viewport 值来指定的。
通过上面的属性可以看出, group 主要是用来设置路径做动画的关键属性的。
最后, vector 还支持 clip-path 元素。定义当前绘制的剪切路径。注意,clip-path 只对当前的 group 和子 group 有效。
android:name 定义 clip path 的名字
android:pathData 和 android:pathData 的取值一样。
从上面 vector 支持的属性可以看出,功能还是比较丰富的。例如 前面提到的三角形,通过 group 可以把其旋转 90度
AnimatedVectorDrawable
我们还可以用AnimatedVectorDrawable给矢量图添加动画。AnimatedVectorDawable可以实现一些很特别的效果,对VectorDrawable里的pathData做动画,可以从一个图形渐变到另一个图形,比如Material Design里的toolbar icon;对trimPathStart、trimPathEnd做动画,可以得到图形的绘制轨迹。
类可以去创建一个矢量资源的动画。
你通常在三个XML文件中定义矢量资源的动画载体:
&vector&元素的矢量资源,在res/drawable/(文件夹)
&animated-vector&元素的矢量资源动画,在res/drawable/(文件夹)
& objectAnimator&元素的一个或多个对象动画器,在res/anim/(文件夹)
矢量资源动画能创建&group&和&path&元素属性的动画。&group&元素定义了一组路径或子组,并且&path&元素定义了要被绘制的路径。
当你想要创建动画时去定义矢量资源,使用android:name属性分配一个唯一的名字给组和路径,这样你可以从你的动画定义中查询到它们。
接下来我就以旋转的小三角为例:
然后在看一下animated-vector文件:
从上面代码我们可以看出配置了两个动画,一个是旋转动画一个是变化形状的动画。
旋转动画:
变化形状动画:
3个TextView,我们只需要关注第一个TextView即可,因为其他都是一样的配置。
配置了一个avb也就是上面贴的animated-vector文件。
最后看一下Activity的启动动画代码:
本文为云栖社区原创内容,未经允许不得转载,如需转载请发送邮件至yqeditor@list.;如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:yqgroup@ 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
用云栖社区APP,舒服~
【云栖快讯】首届阿里巴巴中间件技术峰会,揭秘阿里10年分布式技术沉淀!阿里高可用体系核心缔造者、全链路压测创始人,DRDS与TDDL负责人等大咖出场,干货分享,不可错过!&&
阿里云移动APP解决方案,助力开发者轻松应对移动app中随时可能出现的用户数量的爆发式增长、复杂的移动安全挑战等...
深度挖掘企业与企业、企业与人物的关系,通过多位交叉分析及智能算法,构建基于企业全息画像和企业关系网络的风险洞察、...
基于领先的内容接入与分发网络和大规模分布式实时转码技术打造的音视频直播平台,提供便捷接入、高清流畅、低延迟、高并...
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...
2017杭州云栖大会火热抢票
Loading...Android VectorDrawable与SVG 实现炫酷动画
从 5.0 提供了新的API VectorDrawable,通过该对象,我们可以使用矢量图SVG。
在编写xml文件中,通过关键的几个标签节点,,完成对SVG 的编写以及动画的实现。
下面我们将实现两个例子来演示VectorDrawable和SVG的使用。先上实现的效果图。
登录特效的实现
首先需要分析该特效。根据整个动画,整个特效对应的SVG 图案如下所示:
整个图案分为五个部分,两条横线,两个半圆,以及一个对号。为了凸显,所以把颜色稍微修改了一下。
那么使用定义xml文件,实现如上图案。
edit_login.xml :该文件存放在res-& drawable文件夹下。
如上代码,我们可以通过Android Studio的预览效果,直接看到图案。
在代码中出现了两个标签,.
:用于定义整个画布。
width:画布的宽度。 height:画布的高度。 viewportWidth:将具体的宽度划分成相对的单位单元。300dp被分割成了150个单元单位。 viewportHeight:将具体的高度划分成相对的单元单位。96dp被分割成48个单元单位。
:用于画出具体的图案,类似于画笔。
name:声明一个标记。类似于id。 便于对其做动画的时候可以找到该节点。 pathData:矢量图SVG 的描述。(后面会提) strokeWidth:画笔的宽度 strokeColor:画笔的颜色 strokeAlpha:透明度 strokeLineCap:画出线条的结束点的形状。正方向或圆角矩形。。。
图案画出以后,需要针对该图案做动画,整个图案过程分为三个:
初次点击第一个对话框时,显示第一条横线,其余的不显示。
1 动画显示。2,3,4,5不显示。 验证输入是否正确,如果正确,显示对号。
1 默认显示,2,3 动画显示 4,5 隐藏 点击第二个对话框,第一条横线个向第二条横线过度。
1 动画隐藏 ,2 隐藏,3显示。 4,5动画显示。
当然,还很很多的用户交互,在此不再做实现。
根据上面的顺序,分别定义anim1.xml,anim2.xml,anim3.xml。注意,该文件存在drawable中。ps: 无视命名.
在三个文件中,最外层进行包裹,该文件的作用类似于沟通的作用,将SVG和动画相整合,产生新的drawable。
drawable:目标SVG.
:对于SVG中的每一个定义不同的动画。
name: 目标文件的标识。 animation:动画。
在其中定义了n多个动画。默认显示和默认不显示的动画(此时没有动画效果).ps: 动画定义的都是属性动画,所以需要放在animator文件夹中。
anim_default.xml 默认显示
动画属性trimPathEnd这个字段之前未出现过。它也是的一个属性,其决定的是节点所画出线条显示的百分比。 0~1 代表 从开始到结束显示的百分比。
同时也有一个trimPathStart,这个字段显示的也是百分比。不过其表示的是不显示的百分比。0~1代表从开始隐藏的百分比。
anim_default_gone.xml 默认隐藏
anim_bar_fill.xml &&1 的显示动画。
anim_bar_empty.xml &&1 的隐藏动画。
anim_round.xml & 2 的显示动画
anim_aa.xml & 3 的显示动画
anim_round2.xml & 4 的显示动画
anim_bar_fill2.xml & 5 的显示动画
如上的代码已经实现了图片以及动画的实现。下面就是使用,首先看布局文件:
两个文本框之间要有间隔,用以显示我们的动画。
由于文本框的存在,导致打开页面是自动弹出键盘,所以把焦点定在了ImageView上,防止打开页面时自动弹出软键盘。
* SVG 动画
* Created by MH on .
public class SVGMainActivity extends AppCompatActivity implements View.OnFocusChangeListener, TextWatcher {
private ImageView img1;
private EditText edit1, edit2;
private AnimatedVectorDrawable anim1, anim2, anim3;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_svg);
img1 = ((ImageView) findViewById(R.id.img1));
edit1 = ((EditText) findViewById(R.id.edit1));
edit2 = ((EditText) findViewById(R.id.edit2));
// 加载SVG
anim1 = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim1);
anim2 = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim2);
anim3 = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim3);
// 设置焦点变化的监听
edit1.setOnFocusChangeListener(this);
edit2.setOnFocusChangeListener(this);
// 文本变化的监听
edit1.addTextChangedListener(this);
public void onFocusChange(View v, boolean hasFocus) {
switch (v.getId()) {
case R.id.edit1:
if (hasFocus) {
img1.setImageDrawable(anim1);
anim1.start();
case R.id.edit2:
if (hasFocus) {
img1.setImageDrawable(anim3);
anim3.start();
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
public void onTextChanged(CharSequence s, int start, int before, int count) {
public void afterTextChanged(Editable s) {
// 内容变化之后,判断内容
if (!TextUtils.isEmpty(s) && edit1.getText().toString().trim().equals(&1234&)) {
Toast.makeText(SVGMainActivity.this, &right&, Toast.LENGTH_SHORT).show();
img1.setImageDrawable(anim2);
anim2.start();
核心的三个步骤;
anim1 = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim1);,将之前编写的xml文件加载为drawable,同时强转为AnimatedVectorDrawable。 img.setImageDrawable(anim1)设置Drawable。 anim1.start():启动动画
因为细节的处理上比较麻烦。所以此处只是做了一个简单的实现。
SVG Path Data
在上面的实现中,定义SVG 图像时,节点中pathData中,用字符和数字描绘了一个图案。
其中主要有如下命令:
M : move to 移动绘制点 L : line to 直线 Z : close 闭合 C : cubic bezier 三次贝塞尔曲线 Q : quatratic bezier 二次贝塞尔曲线 A : 圆弧
每个命令都有大写和小写,大写代表绝对位置。小写代表当前点的相对位置。
在使用中,唯一个需要说的便是圆弧(A)问题。
在代码中使用了M138 23 A 10 10 0 1 0 128 13。
M138 23:先画笔移动到(138,23)的位置。 A 10 10 0 1 0 128 13: 画圆弧。分别对应: x轴半径,y轴半径,x轴偏移量,弧度(0代表取小弧度,1代表大弧度) ,方向(0取逆时针,1为顺时针),目标X坐标,目标y坐标。
搜索特效的实现
按照之前的步骤,分别如下实现:
定义SVG图像。 定义VectorDrawable的xml文件。 定义动画。 加载,使用。
search_bar.xml 画出SVG.
anim_bar_to_search.xml 下划线向搜索图案的过渡。
anim_search_to_bar.xml 搜索向下划线过渡的动画
下划线消失和隐藏的动画使用的是上一个例子的动画。代码不在贴。
搜索框的动画和下划线动画类似。
布局文件:
&framelayout android:focusable="true" android:focusableintouchmode="true" android:layout_height="wrap_content" android:layout_width="wrap_content"&
&/framelayout&
布局文件,在最外层添加点击事件,当点击文本框之外时,显示搜索图标。点击图标时显示下划线。同时,将焦点设置移开文本框。
在activity中设置:
* 搜索动画的实现
* Created by MH on .
public class SVGMain2Activity extends AppCompatActivity {
private ImageV
private TextV
private AnimatedVectorDrawable searchToB
private AnimatedVectorDrawable barToS
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_svg2);
iv = (ImageView) findViewById(R.id.search);
text = (TextView) findViewById(R.id.text);
// 加载SVG
searchToBar = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim_search_to_bar);
barToSearch = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.anim_bar_to_search);
// 设置监听
iv.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
iv.setImageDrawable(searchToBar);
searchToBar.start();
public void lost_focus(View view) {
// 点击文本框之外时,隐藏下划线
iv.setImageDrawable(barToSearch);
barToSearch.start();

我要回帖

更多关于 ps如何制作矢量图 的文章

 

随机推荐