转载地址: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. sql通配符+sql中查询条件包含下划线等通配符的写法

    一.SQL 通配符 在搜索数据库中的数据时,SQL 通配符可以替代一个或多个字符. SQL 通配符必须与 LIKE 运算符一起使用. 在 SQL 中,可使用以下通配符: 通配符 描述 % 替代一个或多 ...

  2. 日志不得应用情况切换强制standby改变状态为primary

    日志不得应用情况切换备库为主库 备库运行如下: alter database recover managed standby database disconnect from session; alt ...

  3. UITableView点击背景

    系统自定义的点击背景有时间觉得效果不好想换个 - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelect ...

  4. BZOJ 1303: [CQOI2009]中位数图 【水题】

    给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. Input 第一行为两个正整数n和b ,第二行为1~n 的排列. Out ...

  5. iOS时钟,秒针扫秒样式

    昨天做一个时钟小demo,发现了一些问题. 描述能力有限,我封装好了一个时钟框架,朋友们可以参考      https://github.com/qianlishun/ClockView 点击这里可以 ...

  6. 八数码难题 双向搜索(codevs 1225)

    题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字 ...

  7. msp430项目编程21

    msp430中项目---直流电机控制系统 1.定时器工作原理 2.电路原理说明 3.代码(显示部分) 4.代码(功能实现) 5.项目总结 msp430项目编程 msp430入门学习

  8. 51nod 马拉松30 C(构二分图+状压dp)

    题意 分析 考虑一个图能被若干简单环覆盖,那么一定是每个点恰好一个出度,恰好一个出度 于是类似最小路径覆盖的处理,我们可以把每个点拆成2个点i和i',如果有一条边(i,j),那么将i和j'连起来 那么 ...

  9. Spring MVC的WebMvcConfigurerAdapter用法收集(零配置,无XML配置)

    原理先不了解,只记录常用方法 用法: @EnableWebMvc 开启MVC配置,相当于 <?xml version="1.0" encoding="UTF-8&q ...

  10. 碰撞检測之Sphere-Box检測

    检測思路 首先要做的是将Box转为AABB,然后推断圆心是否在Box内.用的就是之前的SAT 假设圆心在Box内,肯定相交, 假设不在圆心内.则有四种情况,与顶点相交,与楞相交,与面相交,这里的确定也 ...