android矢量图vector的简单介绍
- vector是用于绘制矢量图的,跟svg非常类似
-
但vector是android5.0的东西,因此想在低版本使用,可以查阅下这篇文章:
Android中vector用法详解_Nothing-CSDN博客_android中vector
- 本文会讲解有关vector的一些知识,了解了这些后一些简单的图形自己完全是有能力手写出来的
vector的宽高属性
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
...
</vector>
- 上面的viewportWidth和viewportHeight可以理解为画布的宽高,而width和height则可以理解为实际的大小,这样的好处就是一切按照比例进行绘制
- 举个例子,当viewportWidth为24,width为48dp时(即1:2),如果指定线的长度为3,那么实际绘制时线对应的长度就是6dp
- 上面的xml中,如果我们将 android:width和android:height改为48dp,那么就相当于对我们的图放大了一倍
- 一般情况下我们都是设定为1:1的比例,这样比较方便理解和计算
pathData
- vector里最重要的内容就是pathData了,pathData就是真正的绘制代码
-
pathData中主要有几种类型,M表示移动到某个点,
L表示画线,A表示弧线,Q是二阶贝塞尔,C是三阶贝塞尔,Z表示闭合,V表示垂直,H表示水平
-
注意以上
字母大写时表示绝对坐标,小写则表示相对坐标
,除了Z不需要参数外,其余字母都有相应的参数要设置 - V和H可以说是L的一种便捷方式,因此V和H不是必须的
- 坐标系是以左上角为原点,向下为y轴正方向,向右为x轴正方向
绘制类型
移动点
-
M(x,y)
- 要绘制任何图形首先得有个起点吧,这个可以用M来表示,参数是坐标
- M表示移动到某个点的意思
直线
-
L(x,y)
- 绘制直线比较简单,用字母L表示,当绘制水平线时可以用H,绘制垂直线时可以用V
- 注意strokeWidth和strokeColor必须指定才能看到绘制的线,否则是看不到的,而且strokeWidth的范围是相对于viewportWidth来说的,也就是不能用单位dp来表达,当我们指定viewportWidth为1时,由于1占了24的二十四分之一,因此我们会发现显示出来的效果就是线太粗了
- L后面主要跟两个参数,就是要绘制的直线的终点坐标,有小伙伴可能会疑惑,难道不用指定起点坐标吗,实际上起点坐标都是以上一个点作为起点坐标
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="
M0,0
L24,24
H0
V0
H24
V24
M0,24
L24,0
M0,12
H24
M12,0
V24
M0,6
H24
M0,18
H24
M6,0
V24
M18,0
V24
"
android:strokeWidth="0.05"
android:strokeColor="@android:color/black" />
</vector>
- 上面的代码的效果如下
这里绘制这个网格是有意义的,有助于我们理解椭圆的绘制
弧线
-
格式为:
A(rx ry x-axis-rotation large-arc-flag sweep-flag x y)
-
也可以按照中文便于记忆:
A(x轴半径,y轴半径 x轴旋转角度 大小弧 顺逆时针 终点坐标)
-
也可以按照中文便于记忆:
-
参数比较多,下面会说明一下:
- 绘制弧线一般会有弧线的起点和终点,起点不用说了,就是上一个点的位置,那么终点就是A最后的x和y
- A中的前两个就是指定半径的
- 至于x-axis-rotation表示x轴旋转角度,本人暂时不理解其作用,取0还是取1暂时没发现有什么影响
- large-arc-flag就是指明要大弧还是小弧,1表示要大弧,0表示小弧
- sweep-flag是说按顺时针还是逆时针,0取逆时针,1取顺时针
- 这么说还是抽象了,下面以实际绘制一个弧线举例
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="
M0,0 L24,24 H0 V0 H24 V24 M0,24 L24,0
M0,12 H24
M12,0 V24
M0,6 H24
M0,18 H24
M6,0 V24
M18,0 V24
"
android:strokeWidth="0.05"
android:strokeColor="@android:color/black" />
<!--顺时针大弧-->
<path
android:pathData="
M12,6
A6,6 0 1 1 6,12
"
android:strokeWidth="0.5"
android:strokeColor="@android:color/white" />
<!--顺时针小弧-->
<path
android:pathData="
M12,6
A6,6 0 0 1 6,12
"
android:strokeWidth="0.5"
android:strokeColor="@android:color/holo_red_dark" />
<!--逆时针小弧-->
<path
android:pathData="
M12,6
A6,6 0 0 0 6,12
"
android:strokeWidth="0.5"
android:strokeColor="@android:color/holo_blue_dark" />
<!--逆时针大弧-->
<path
android:pathData="
M12,6
A6,6 0 1 0 6,12
"
android:strokeWidth="0.5"
android:strokeColor="@android:color/holo_green_dark" />
</vector>
- 绘制效果如下
- 到了这里,如果想绘制一个圆怎么办,其实圆说白了就是两个半圆弧组成的,因此绘制两个半圆弧即可
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="
M0,0 L24,24 H0 V0 H24 V24 M0,24 L24,0
M0,12 H24
M12,0 V24
M0,6 H24
M0,18 H24
M6,0 V24
M18,0 V24
"
android:strokeWidth="0.05"
android:strokeColor="@android:color/black" />
<path
android:pathData="
M18,12
A6,6 0 1 0 6,12
A6,6 0 1 0 18,12
"
android:strokeWidth="0.5"
android:strokeColor="@android:color/white" />
</vector>
- 其中 A6,6 0 1 0 6,12绘制上半段弧, A6,6 0 1 0 18,12绘制了下半段弧,注意下面的A是以上一个A的终点作为起点的
贝塞尔曲线
二阶
- 假设从a(Xa,Ya)点到b(Xb,Yb)点的二阶贝塞尔(只有一个控制点),可以设置控制点c(Xc,Yc),那么写法就是 QXc,Yc Xb,Yb,例如
Q1,1 2,2
- 再具体点,以绘制一个聊天背景框为例,这里我们设定我们的画布大小为20*10,那么接下来的坐标我们都需要在这个x属于[0,20] ,y属于[0,10]这个范围内,然后聊天对话框的边角是圆角,圆角本来也可以用椭圆A来绘制,但此处我们使用二阶贝塞尔Q来实现
- 整个绘制分为两部分,一部分是绘制圆角矩形,一部分是绘制底下的三角形(这部分比较简单就不阐述了)
- 绘制圆角矩形的话,我们先用M移动到我们需要绘制的第一个圆角的位置即左上角,作为贝塞尔曲线的起始点,然后按逆时针方向依次绘制圆角,向下竖线,圆角,向右横线,圆角,向上竖线,圆角,这样一个圆角矩形就绘制完成了
- 示例代码如下:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="10dp"
android:tint="#417FF9"
android:viewportWidth="20"
android:viewportHeight="10">
<path
android:fillColor="@android:color/white"
android:pathData="
M1,0
Q0,0 0,1
V8
Q0,9 1,9
L19,9
Q20,9 20,8
V1
Q20,0 19,0
M9.5,9
H10.5
L10,10
z" />
</vector>
- 以上代码绘制出的效果图就是这样
三阶
- 三阶贝塞尔曲线用大写C或小写c表示,后面跟三个坐标点的坐标,分别是控制点1,控制点2,和终点坐标,坐标中间用空格隔开
- 假设要绘制从a(Xa,Ya)点到b(Xb,Yb)点的三阶贝塞尔(有两个控制点),可以设置控制点c(Xc,Yc)和d(Xd,Yd),那么写法就是 CXc,Yc Xd,Yd Xb,Yb,例如
C0,0 1,1 2,2
- 这里可能有人会疑惑,为何起始点a的坐标没体现出来,因为起始点就是从上一个点开始的,比如你可以通过M移动到某个点e或者通过L到达点e,接着再绘制贝塞尔,那么这个e点就是贝塞尔曲线的起始点
参考
版权声明:本文为huweijian5原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。