转载地址:http://www.jianshu.com/p/a3cb1e23c2c4#rd

Android Support Library 23.2 出来以后,在Android 5.0(API级别21)以前的系统中,也可以定义矢量drawables,即VectorDrawable。它可以在不失清晰度的情况下进行缩放。你仅仅需要需要一个矢量图片的资源文件,而不再需要为每个屏幕密度设置一个资源文件,在一定程度上可以减小项目的体积。

vector 标签下的最主要就是 pathData,其实pathData跟Android中 Path api对路径的定义规则是差不多的,当你掌握了 pathData 的语法,同时有一颗不轻易放弃的心,就可以通过一些简洁的指令完成几乎所有的图案。

越是复杂的东西往往越有规律可循。下面就来详细说说pathData 的语法。给我五!

give me five.png
<!--上面的手掌对应的代码实现-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000000"
android:pathData="
M22,23 q0,4 -4,4 h-7 q-2,0 -3,-1 T1,16 q-0.6,-0.8 0,-2 t5,3
q1,1 2,0 T8,4 q0,-1 0.9,-1.1 t1.1,1 1.5,9 q0.25,0.5 0.5,0.5
t0.5,-0.5 0,-11 q0.2,-1 1.1,-1.1 t1.1,1.1 1,11 q0.25,0.5 0.5,0.5
t0.5,-0.5 0.5,-9 q0.2,-1 1,-1 t1,1 0.5,9 q0.25,0.5 0.5,0.5
t0.5,-0.5 1.2,-6.5 q0.3,-1 1,-1 t0.8,1 -0.8,6 T22,23"/>
</vector>

基本规则

pathData 的指令基本都是由字母跟若干数字组成,数字之间可以用空格或者逗号隔开 (其实逗号会被忽略掉,加上逗号只是一些习惯的问题)。一般来说指令字母分为大小写两种,大写的字母是基于原点的坐标系(偏移量),即绝对位置;小写字母是基于当前点坐标系(偏移量),即相对位置。

移动

  • M x,y (m dx, dy) 移动虚拟画笔到对应的点,但是并不绘制。一开始的时候默认是在(0,0)。

直线

  • L x,y (l dx, dy) 从当前点划一条直线到对应的点。
  • H x (h dx) 从当前点绘制水平线,相当于l x,0
  • V y (v dy) 从当前点绘制垂直线,相当于l 0,y
    <!--下面的例子除了 pathData, 其他跟此文件一样-->
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
    android:fillColor="#0000"
    android:strokeColor="#000"
    android:strokeWidth="0.2"
    android:pathData=" M10,10 L10,15 L15,15 L10,10"/>
    </vector>

直线

将上述代码 android:pathData=" M10,10 L10,15 L15,15 L10,10" 替换成以下代码效果相同

 android:pathData="M10,10 l 0,5 l 5,0 l-5,-5"
android:pathData="M10,10 V 15 H 15 L10,10"
android:pathData="M10,10 v 5 h 5 l-5,-5"

闭合

  • Z(或z) 从结束点绘制一条直线到开始点,闭合路径

上面的图形型也可以由以下代码绘制
android:pathData="M10,10 v 5 h 5 z"

弧线

  • A rx,ry x-axis-rotation large-arc-flag,sweepflag x,y
  • a rx,ry x-axis-rotation large-arc-flag,sweepflag dx,dy

    rx ry 椭圆半径
    x-axis-rotation x轴旋转角度
    large-arc-flag 为0时表示取小弧度,1时取大弧度(要长的还是短的)
    sweep-flag 0取逆时针方向,1取顺时针方向
    x,y (dx,dy) 终点的位置

这个弧线的指令比起直线就相对复杂得多了,7个参数容易搞混了。来看个例子
android:pathData="M8,10 a4,6 0 1,1 6 6"

弧线 (大弧,顺时针)

红色(8,10) 是起点, X轴旋转的角度为0,取大弧,顺时针,蓝色(14,16) 是终点。

  • 只将x-axis-rotation 改为30跟-30分别对应下面左边跟右边的效果,可见正数是按顺时针旋转负数按逆时针旋转。

    x-axis-rotation为30(左)、-30(右)
  • 只将large-arc-flag 改为 0 android:pathData="M8,10 a4,6 0 0,1 6 6" 对应下图效果

large-arc-flag为 0
  • 只将sweep-flag改为 0 android:pathData="M8,10 a4,6 0 1,0 6 6" 对应下图效果

sweep-flag为0

网上看到一张图,基本总结了弧线

二阶贝塞尔曲线

  • Q x1,y1 x,y ( q dx1,dy1 dx,dy)
  • T x,y ( t dx, dy)

先来看看二阶贝赛尔曲线的公式

没想到高数(高中数学)考过149分的我也研究不透这个鬼,还是看看动画吧

一下子感觉清晰了不少,对于Q指令来说(x1,y1)就是P1这个控制点,(x,y)就是终点P2。P0当然就是执行指令前最后的位置。这里有一点需要说明的, q dx1,dy1 dx,dy 这个指令,两个控制点都是相对P0点的。

而T指令又是什么鬼?为什么只有两个参数?其实T指令是在你画完一条贝塞尔曲线后,只需用T指令指定终点,就能画出一条平滑的贝塞尔曲线。控制点被默认为上一次的控制点关于上次终点的中心对称点。比如上次的控制点P1是(6,6),终点P2是(8,10),
那么使用T指令后默认控制点P1`为(10,14)。

举个例子:

 android:pathData="M4,10 Q6,6 8,10 Q10,14 12,10"
android:pathData="M4,10 Q6,6 8,10 T12,10"
android:pathData="M4,10 q2,-4 4,0 q2,4 4,0"
android:pathData="M4,10 q2,-4 4,0 t4,0"

这四个对应的都是下面的曲线

二阶贝塞尔

三阶贝塞尔曲线

  • C x1,y1 x2,y2 x,y ( c dx1,dy1 dx2,dy2 dx,dy)
  • S x1,y1 x,y ( s dx1,dy1 dx, dy)

同样,先列下公式

这玩意估计也看不懂,还是结合动画来吧

跟二阶类似,但是三阶有两个控制点,分别是P1(x1,y1),P2(x2,y2)还有终点P3(x,y)。类似的, c dx1,dy1 dx2,dy2 dx,dy 所有的点都是相对于P0,即上一次的终点。

S指令跟T指令类似。S指令相对于C指令少了一个控制点,这个控制点就是上一次最后一个控制点相对上次的终点的中心对称点。还是同样举个例子:

 android:pathData="M4,10 C6,6 8,14 10,10 C12,6 14,14 16,10"
android:pathData="M4,10 C6,6 8,14 10,10 S14,14 16,10"
android:pathData="M4,10 c2,-4 4,4 6,0 c2,-4 4,4 6,0"
android:pathData="M4,10 c2,-4 4,4 6,0 s4,4 6,0"

以上四个均会出现下图的效果

三阶贝塞尔

实践

终于把所有的指令搞清楚啦,那么接下来就来画一个比较简单的图案吧(为了一次性涉及几乎所有的指令,大家就别在意图画的很丑啦)

首先分析一下这个图的构成。它是一个圆角正方形同时里面有一个镂空的心型。先来看看正方形

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="40"
android:viewportHeight="40"> <path
android:fillColor="#f24e4e"
android:pathData="M8,4
h24 q4,0 4,4 v24 q0,4 -4,4
h-24 q-4,0 -4,-4 v-24 q0,-4 4,-4"/>
</vector>

Paste_Image.png

细心的同学应该注意到这里没有设置strokeColor,strokeWidth,并且fillColor也不再设置透明了,所以出现的是没有边框的填充效果。上面viewportWidth为40,则把这张图分成40个单位。

在pathData中,首先移动到A(8,4),然后水平移动了24个单位到B(32,4)。接着就是一条二阶贝塞尔曲线,起点是B,控制点是C(36,4),终点是D(36,8)。然后再画一条垂直线到(36,32)…下面的操作都是差不多,就不多说的。这里注意一点,画这个正方形是从A-B-C-D,也就是顺时针的方向,这点对接下来画心型很重要。

画完了圆角正方形,接下来就要画一个镂空的心型。有同学说再加上一个path标签,设置不同颜色就可以。这方法乍一看挺不错,但是他实现的并不是镂空的效果,而是叠加的效果。镂空的话中间的心型是透明的,但是叠加就没办法让中间的心呈透明。

那怎么实现镂空的效果呢?其实关键就是前面说的方向。前面的正方形是顺时针的方向,如果我们在pathData 后面加上另一逆时针方向的路径,就会出现取反的效果,比如

    <path
android:fillColor="#f24e4e"
android:pathData="M8,4
h24 q4,0 4,4 v24 q0,4 -4,4
h-24 q-4,0 -4,-4 v-24 q0,-4 4,-4
M2,20 h20 v-10 z"/>

在刚才的基础上加上M2,20 h20 v-10 z ,这是一个逆时针方向的三角形,会变成下面这样

也就是说,我们只需要画一个逆时针方向的心型,就会出现上面的那个效果。先看看代码

    <path
android:fillColor="#f24e4e"
android:pathData="M8,4
h24 q4,0 4,4 v24 q0,4 -4,4
h-24 q-4,0 -4,-4 v-24 q0,-4 4,-4
M20,15
a5,6 -15 0 0 -9,2
c0,5 4,6 9,12
c5,-6 9,-7 9,-12
a5,6 15 0 0 -9 -2"/>

这个是在正方形的基础上加上

            M20,15
a5,6 -15 0 0 -9,2
c0,5 4,6 9,12
c5,-6 9,-7 9,-12
a5,6 15 0 0 -9 -2

我们看看如果pathData 单独设为上述路径会是什么样的

果然很漂亮。首先它从白色的点
(20,15)开始,向逆时针方向,也就是右边画了一段圆弧到蓝色的点(11,17),圆弧所在的椭圆逆时针转15°,取短弧,逆时针。然后再画一条三阶贝塞尔曲线,控制点分别是黄点(11,22),黑点(15,23),终点是绿色的点(20,
29)。这样子就完成了心型的一半了。另一半跟这边的完全对称,也就不细说了。

完整代码

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="40"
android:viewportHeight="40"> <path
android:fillColor="#f24e4e"
android:pathData="M8,4
h24 q4,0 4,4 v24 q0,4 -4,4
h-24 q-4,0 -4,-4 v-24 q0,-4 4,-4
M20,15
a5,6 -15 0 0 -9,2
c0,5 4,6 9,12
c5,-6 9,-7 9,-12
a5,6 15 0 0 -9 -2"/> </vector>

一些废话

网上很多介绍VectorDrawable,但是介绍pathData的真的有点少。我也是通过查阅大量的资料,加上实践,基本算对pathData语法入门了吧,这东西掌握了真的不难,还可以装逼哈哈。这篇博客写的时间真的有点长,整整一天,第一写很多不懂的,希望大家多多指教。有机会再写一下Animated Vector Drawables。

文/DomenCai(简书作者)
原文链接:http://www.jianshu.com/p/a3cb1e23c2c4#rd
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

Android vector 标签 pathData 详解的更多相关文章

  1. Android vector标签 PathData 画图超详解

    SVG是一种矢量图格式,是Scalable Vector Graphics三个单词的首字母缩写.在xml文件中的标签是<vector>,画出的图形可以像一般的图片资源使用,例子如下: &l ...

  2. Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

    Android XML shape 标签使用详解   一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...

  3. Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

    Android XML shape 标签使用详解   一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...

  4. 《Android NFC 开发实战详解 》简介+源码+样章+勘误ING

    <Android NFC 开发实战详解>简介+源码+样章+勘误ING SkySeraph Mar. 14th  2014 Email:skyseraph00@163.com 更多精彩请直接 ...

  5. Android中Service(服务)详解

    http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...

  6. [转]ANDROID L——Material Design详解(动画篇)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 转自:http://blog.csdn.net/a396901990/article/de ...

  7. Android屏幕适配问题详解

    上篇-Android本地化资源目录详解 :http://www.cnblogs.com/steffen/p/3833048.html 单位: px(像素):屏幕上的点. in(英寸):长度单位. mm ...

  8. Android开发–Intent-filter属性详解

    Android开发–Intent-filter属性详解 2011年05月09日 ⁄ Andriod ⁄ 暂无评论 ⁄ 被围观 1,396 views+ 如果一个 Intent 请求在一片数据上执行一个 ...

  9. Android目录结构(详解)

    Android目录结构(详解) 下面是HelloAndroid项目在eclipse中的目录层次结构: 由上图可以看出项目的根目录下共有九个文件(夹),下面就这九个文件(夹)进行详解: 1.1src文件 ...

随机推荐

  1. js总结(三):面向对象,prototype ,oo模拟

    http://aralejs.org/class/docs/competitors.html http://javascript.crockford.com/prototypal.html proto ...

  2. Javascript拼接HTML字符串的方法列举及思路

    转载过来,去掉一些废话吧. 目标: 方便的拼接字符串,不使用让人眼晕的+=.使用过程如下: 1,先创建一个作为“模板”的字符串,如:’My name is ${name},I\’m ${age}.’ ...

  3. Flask设计带认证token的RESTful API接口[翻译]

    上一篇文章, 使用python的Flask实现一个RESTful API服务器端  简单地演示了Flask实的现的api服务器,里面提到了因为无状态的原则,没有session cookies,如果访问 ...

  4. 任意两点间最短距离floyd-warshall ---- POJ 2139 Six Degrees of Cowvin Bacon

    floyd-warshall算法 通过dp思想 求任意两点之间最短距离 重复利用数组实现方式dist[i][j] i - j的最短距离 for(int k = 1; k <= N; k++) f ...

  5. Shell脚本的编写,sed的使用以及一些正则表达式

    Shell脚本的简单编写以及sed的使用 标签(空格分隔): 博客文章 前一阵子为了批量修改Web审计规则,故编写了一个Shell脚本,顺便使用了下sed,顺便把正则表达式也重新学习一遍,感觉还是需要 ...

  6. OC-Xcode中导入runtime框架,函数参数没有提示的处理方法

    在了解runtime时,如果自己编写runtime代码,需要先导入头文件: #import <objc/message.h> 之后,例如了解runtime的消息机制时,调用objc_msg ...

  7. HDU——2444 The Accomodation of Students

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  8. hdu6212 祖玛(区间DP)

    题意 有一个长度为n的01串,我们可以在某个地方插入一个0或者1,那么如果有连续颜色相同的>=3个,那么这段就会消去,两边的合拢.问将所有01串消去,最少需要插入多少个.(n<=200) ...

  9. Win7中你所应该知道的强制计划关机操作

    有时候更新系统补丁时,需要很长时间,为了能让电脑在你晚上睡觉后,扔然能做些枯燥费时类的这种工作,你可以用到强制计划关机.cmd命令是: shutdown -f -s -t 3600 上面的意思是,强制 ...

  10. Android Studio 经常使用手冊

    经常使用小操作 单词选择 显示近期操作 改动的文件 文件查找 操作记录 移动行 查找方法调用处 方法的跟进 显示方法的參数 行的高速操作 多行操作 高速补全完毕 代码提示 变量的高速操作 代码折叠 预 ...