<p>之前经常看到一些酷酷的图标效果, 深入进去发现不是直接用的图片, 而是一些以Vector标签开头的xml文件, 于是就看到了如下代码:</p><pre class="brush:xml;toolbar:false"><vectorxmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="40"
android:viewportWidth="40">
<path
android:fillColor="#f24e4e"
android:pathData="
M8,4
h24,0
q4,04,4
v24
q0,4-4,4
h-24,0
q-4,0-4,-4
v-24
q0,-44,-4
M20,15
a5,6-150,0-92
C11,2215,2320,29
C25,2329,2229,17
a5,6150,0-9,-2"/>
</vector></pre><p>效果还是挺赞的, 圆角矩形中部有个镂空的心形. 代码就是上面的那些代码.<br/></p><p><img src="/up_pic/201812/210920051327.png" title="210920051327.png" alt="1.png"/></p><p>首先看下属性(这里只挑一些个人认为比较重要的) :</p><pre class="brush:java;toolbar:false">android:viewportHeight="40"//将width等分为40份
android:viewportWidth="40"//将height等分为40份</pre><p>以下是pathData中用到的:</p><pre class="brush:diff;toolbar:false">M:moveto移动绘制点,作用相当于把画笔落在哪一点。
L:lineto直线,就是一条直线,注意,只是直线,直线是没有宽度的,所以你什么也看不到。
Z:close闭合,嗯,就是把图封闭起来。
C:cubicbezier三阶贝塞尔曲线
Q:quatraticbezier二阶贝塞尔曲线
A:ellipse圆弧</pre><p>基本规则</p><p>pathData 的指令基本都是由字母跟若干数字组成,数字之间可以用空格或者逗号隔开 (其实逗号会被忽略掉,加上逗号只是一些习惯的问题)。一般来说指令字母分为大小写两种,大写的字母是基于原点的坐标系(偏移量),即绝对位置;小写字母是基于当前点坐标系(偏移量),即相对位置。</p><p>移动:</p><p>M(X,Y) 移动到指定点(X,Y), m(dx,dy)表示移动到相对当前点的相对dx,dy坐标位置</p><p>划线:</p><p>L(X,Y) 从当前点划线到(X,Y), l(dx,dy)表示划线到相对当前点dx距离,dy距离坐标位置</p><p>H(X)水平方向划线: y坐标保持不变,划线到x坐标位置, h(dx)表示划线到距离当前坐标dx距离位置(y坐标保持不变)</p><p>V(Y)竖直方向划线: x坐标保持不变,划线到y坐标位置, v(dy)表示划线到距离当前坐标dy距离位置(x坐标保持不变)</p><p>弧线:</p><p>A rx,ry x-axis-rotation large-arc-flag,sweepflag x,y</p><p> a rx,ry x-axis-rotation large-arc-flag,sweepflag dx,dy</p><p>rx ry表示画弧的半径, x-axis-rotation 表示沿x轴旋转角度, large-arc-flag为0时表示取小弧线,为1时表示取大弧线</p><p> sweepflag为0时表示逆时针方向画弧,为1时表示顺时针方向画弧. x,y表示终点目标的坐标,dx,dy表示起到到终点相对坐标距离.</p><p>好了, 看到这里我们就可以绘制以下图形了:</p><p><img src="/up_pic/201812/210920494692.png" title="210920494692.png" alt="2.png"/></p><p>分析: 此图可由4段线段加上4个圆弧构成,将画布分成40份, 则对应关键点的坐标如下图所示:</p><p><img src="/up_pic/201812/210920531268.png" title="210920531268.png" alt="3.png"/></p><p>对应代码:</p><pre class="brush:xml;toolbar:false"><vectorxmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="40"
android:viewportWidth="40">
<path
android:fillColor="#f24e4e"
android:pathData="
M8,4
h24,0
q4,04,4
v24
q0,4-4,4
h-24,0
q-4,0-4,-4
v-24
q0,-44,-4"/>
</vector></pre><p>先移动到(8,4)点,然后画水平直线,然后根据起始点 控制点 终点可以画出右上角的圆弧,然后画竖直线段,以此类推,这个图形就轻而易举的画出来了,是不是挺简单,好,继续深入.为了画出心形图案,还需要学习贝塞尔曲线才能画出.</p><p>二阶贝塞尔曲线:</p><p> Q x1,y1 x,y ( q dx1,dy1 dx,dy)</p><p> 对应的贝塞尔二阶公式为</p><p><img src="/up_pic/201812/210921174651.gif" title="210921174651.gif" alt="1.gif"/></p><p>三阶阶贝塞尔曲线:</p><p> Q x1,y1 x2,y2 x,y ( q dx1,dy1 dx2,dy2 dx,dy)</p><p> 对应的贝塞尔三阶公式为</p><p><img src="/up_pic/201812/210921221515.gif" title="210921221515.gif" alt="2.gif"/></p><p>也就是说为了完成一个二阶贝塞尔曲线,需要确定一个起始点,一个控制点和一个终点,依次传入参数,所以这里的重点是控制点的确定,三阶的也是这样,需要起始点,两个控制点和一个终点.</p><p>先画个心形图案练练手吧.</p><p>图形解析:</p><p><img src="/up_pic/201812/210921362102.png" title="210921362102.png" alt="1.png"/></p><p>根据图片可以看出需要4段弧线组成这个心形, 上边的两段圆弧和下边的两段曲线,各个弧线的起始点和控制点,终点都确定了,接下来就简单了,上代码:</p><pre class="brush:xml;toolbar:false"><vectorxmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="40"
android:viewportWidth="40">
<path
android:fillColor="#f24e4e"
android:pathData="
M20,15
a5,6-150,0-92
C11,2215,2320,29
C25,2329,2229,17
a5,6150,0-9,-2"/>
</vector></pre><p>接下来就可以考虑画出文章开始给出的那个镂空心形图,由于中间是镂空的,所以采取两个pathData标签叠加不可取,可以先顺时针画出矩形,然后逆时针画出心形就可以了.</p><pre class="brush:xml;toolbar:false"><vectorxmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="40"
android:viewportWidth="40">
<path
android:fillColor="#f24e4e"
android:pathData="
M8,4
h24,0
q4,04,4
v24
q0,4-4,4
h-24,0
q-4,0-4,-4
v-24
q0,-44,-4
M20,15
a5,6-150,0-92
C11,2215,2320,29
C25,2329,2229,17
a5,6150,0-9,-2"/>
</vector></pre><p>代码就是这样了,是不是挺简单,最起码又一个知识点get了</p><p>多个pathData标签叠加需要使用<group></group>, 另外还有一些属性,</p><p>path</p><p>android:name 定义该 path 的名字,这样在其他地方可以通过名字来引用这个路径</p><p>android:pathData 和 SVG 中 d 元素一样的路径信息。</p><p>android:fillColor 定义填充路径的颜色,如果没有定义则不填充路径</p><p>android:strokeColor 定义如何绘制路径边框,如果没有定义则不显示边框</p><p>android:strokeWidth 定义路径边框的粗细尺寸</p><p>android:strokeAlpha 定义路径边框的透明度</p><p>android:fillAlpha 定义填充路径颜色的透明度</p><p>android:trimPathStart 从路径起始位置截断路径的比率,取值范围从 0 到1</p><p>android:trimPathEnd 从路径结束位置截断路径的比率,取值范围从 0 到1</p><p>android:trimPathOffset 设置路径截取的范围,取值范围从 0 到1</p><p>android:strokeLineCap 设置路径线帽的形状,取值为 butt, round, square.</p><p>android:strokeLineJoin 设置路径交界处的连接方式,取值为 miter,round,bevel.</p><p>android:strokeMiterLimit 设置斜角的上限</p><p>group :主要是用来设置路径做动画的关键属性的</p><p>android:name 定义 group 的名字</p><p>android:rotation 定义该 group 的路径旋转多少度</p><p>android:pivotX 定义缩放和旋转该 group 时候的 X 参考点。该值相对于 vector 的 viewport 值来指定的。</p><p>android:pivotY 定义缩放和旋转该 group 时候的 Y 参考点。该值相对于 vector 的 viewport 值来指定的。</p><p>android:scaleX 定义 X 轴的缩放倍数</p><p>android:scaleY 定义 Y 轴的缩放倍数</p><p>android:translateX 定义移动 X 轴的位移。相对于 vector 的 viewport 值来指定的。</p><p>android:translateY 定义移动 Y 轴的位移。相对于 vector 的 viewport 值来指定的。</p><p>clip-path:定义当前绘制的剪切路径。注意,clip-path 只对当前的 group 和子 group 有效</p><p>android:name 定义 clip path 的名字</p><p>android:pathData 和 android:pathData 的取值一样。</p><p>vector:定义这个矢量图</p><p>android:name 定义该drawable的名字</p><p>android:width 定义该 drawable 的内部(intrinsic)宽度,支持所有 Android 系统支持的尺寸,通常使用 dp</p><p>android:height 定义该 drawable 的内部(intrinsic)高度,支持所有 Android 系统支持的尺寸,通常使用 dp</p><p>android:viewportWidth 定义矢量图视图的宽度,视图就是矢量图 path 路径数据所绘制的虚拟画布</p><p>android:viewportHeight 定义矢量图视图的高度,视图就是矢量图 path 路径数据所绘制的虚拟画布</p><p>android:tint 定义该 drawable 的 tint 颜色。默认是没有 tint 颜色的</p><p>android:tintMode 定义 tint 颜色的 Porter-Duff blending 模式,默认值为 src_in</p><p>android:autoMirrored 设置当系统为 RTL (right-to-left) 布局的时候,是否自动镜像该图片。比如 阿拉伯语。</p><p>android:alpha 该图片的透明度属性</p>