绘画是自定义View的基础,Paint和canvas相当于绘画中的画笔和纸,掌握Paint和canvas可以使我们更加容易进行自定义View。
Paint:
一、setAntiAlias()
一般用于绘制不规则图形的时候,使用抗锯齿,比如圆形、文字等。对于规则的图形,是不需要打开抗锯齿功能的,比如矩形。
二、setStyle()
设置填充的样式,主要用于控制几何图形
- Paint.Style.FILL 填充内部
- Paint.Style.FILL_AND_STROKE 填充内部和描边
- Paint.Style.STROKE 仅描边
三、setStrokeWidth()
设置画笔的宽度,单位是px.对画笔的STYLE设置成STROKE和FILL_AND_STROKE时有效。但画支线时无论style设置什么值,均有效。
当设置较大stroke画圆,并且绘画的范围占满(基本占满)画布或rect时,stroke会超出绘画范围。此时需要将原来的圆半径减去stroke一半得到的长度作为新圆的半径。stroke超出的长度其实为stroke宽度的一半。
对于椭圆也差不多:
四、Paint.Cap
Cap指定了描边线和路径的开始和结束的处理。默认为BUTT。
- Paint.Cap.BUTT 无线帽
- Paint.Cap.ROUND 圆形线帽
- Paint.Cap.SQUARE 方形线帽
五、Paint.Join
Join指定线条和曲线段在描边路径上连接的处理。默认为MITER。
- Paint.Join.BEVEL 连接的外边缘以直线相交
- Paint.Join.MITER 连接的外边缘以锐角相交
- Paint.Join.ROUND 连接的外边缘以圆弧相交
Canvas:
一、画背景
canvas提供3种方法可以用于绘制画布的背景
void drawColor(int color)
void drawARGB(int a,int r,int g,int b)
void drawRGB(int r,int g,int b)
复制代码
二、画直线
- startX: 起始点X坐标
- startY: 起始点Y坐标
- stopX: 终点X坐标
- stopY: 终点Y坐标
void drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
复制代码
三、画矩形
矩形的范围可以使用两个矩形工具类进行设置:Rect 和 RectF,两者的主要区别就是Rect存储的上下左右均为Int类型,而RectF存储的上下左右均为Float类型。
- rect 矩形的范围
- rx 生成圆角的x轴半径
- ry 生成圆角的y轴半径 但drawRoundRect()方法只能生成四个圆角都是一致的矩形: 如果想生成圆角不一致的圆角,可使用shape标签:
四、画弧
- RectF 圆弧绘画的矩形范围。
- startAngle 开始的角度。
- sweepAngle 整条弧跨越的弧度。
- useCenter 如果为true,则在弧形中包含椭圆的中心并闭合它。 画笔不同的style和drawArc()useCenter的值可绘画出不同的圆弧或弧线:
注意事项:
canvas画弧时,0度的起始位置在x轴正方向上。
五、画文字
- text 绘画的文本
- start 第一个字符的索引
- end 文本的最后一个字符的索引
- x 文本绘画的起始x轴位置
- y 基线(BaseLine)
前面几个参数都很好理解,无非就是文本、索引值和绘画起始的x轴位置,但基线是什么,怎么求呢? Baseline是文字绘制时所参照的基准线,观察下图可看见基线是大部分英文字母的底部沿线。只有确定Baseline的位置,才能将文字准确的绘制在我们想要的位置上。
需要先理清楚一些概念:1、基线并不是中心线
2、FontMetricsInt.top表示BaseLine到顶部的距离
3、FontMetricsInt.bottom表示BaseLine到底部的距离
4、dy表示BaseLine到中心线的距离
5、BaseLine = 中心线 + dy
6、dy = 中心线 - FontMetricsInt.bottom。因为FontMetricsInt.bottom表示BaseLine到底部的距离。
7、FontMetricsInt.top是一个负值,FontMetricsInt.bottom是一个正数。所以求改文字的中心线时,等于(FontMetricsInt.bottom - FontMetricsInt.top)/ 2
中心线是按文字的所在的位置决定的。以联系人中的字母索引列表为例,每个字母的所需要绘画的高都不一样,需要计算每个字母可占据的高度,再除以一半求出中心线的位置。 六、裁剪
剪切是对canvas的裁剪操作,并不影响原来的之前已经画好的图形。
以clipRect()裁剪变色字体为例:
七、save()和restore()
每次调用save(),都会先保存当前画布的状态,然后将其放入到特定的栈中。
每次调用restore(),都会把栈顶的画布取出来,并按照这个状态恢复当前的画布,然后在这个画布上作画。
clipXX系列的函数对画布的操作是不可逆的,除非调用了save()和restore()对画布进行保存和恢复。
Path:
path代表路径,在canvas中使用drawPath(Path,Paint)进行绘画路径。
一、画直线路径void moveTo(float x1,float y1)
void lineTo(float x2,float y2)
void close()
复制代码
(x1,y1)是直线的起始点,(x2,y2)是直线的终点,又是下一个绘制直线路径的起始点,lineTo可以无限用。
调用了moveTo()后,调用lineTo()画了N条直线,还没有形成闭环的话,可以调用close()将路径的首尾连接起来。
二、画弧形路径
1、调用addXX系列函数,直接添加固定形状的路径
2、moveTo()改变起始位置
调用4参的arcTo()方法,将第4个参数forceMoveTo设置为true,会使弧的起始点作为绘制的起始点。
三、addXXX系列函数
路径默认是连贯的,但addXXX()系列函数可以直接添加一些固定形状的路径,不必考虑连贯性。
1、添加矩形路径
- Path.Direction.CCW: 指创建逆时针方向的矩形路径。
- Path.Direction.CW: 指创建顺时针方向的矩形路径。
目前顺时针和逆时针的生成对矩形图形并无影响,但对于根据路径方向绘画文字等,则会起到关键作用。
2、添加圆角矩形路径
3、添加圆形路径
4、添加椭圆路径
5、添加圆弧路径
具体参数和canvas绘制圆弧一样
补充:
一、测量文本宽高
1、通过Paint.measureText测量文本宽度
2、通过Paint.getTextBounds获得文字所在的矩形区域,可以的到宽高
3、通过Paint.FontMetrics or Paint.FontMetricsInt获得文本宽度
demo链接: 链接:pan.baidu.com/s/1GrP1XYFg… 提取码:wubw