本篇为读HenCoder的总结,之后总结会持续跟进,如有错误,请指出
原文链接:http://hencoder.com/ui-1-1/
简单介绍
-
方式:重写绘制方法,常见的是
onDraw()
-
绘制的关键:
Canvas
-
Canvas
绘制的关键方法:drawXXX()
(关键参数:Paint(颜色和风格信息)
)drawXXX()
能画什么?画方,画圆,画图像,画文字,组合绘制Paint
能设置什么?颜色,线条粗细,实心空心,有没有阴影,拐角要什么形状,开不开双线性过滤,加不加特效
-
-
Canvas
绘制的辅助类:范围裁切(clipXXX()
)和几何变换(Matrix
) -
当对遮盖关系有特殊要求时,注意绘制顺序,实现不同的绘制方法:
onDraw()
只是主体绘制;类似的还有背景绘制,前景绘制,整体绘制
简单绘制
1.画颜色drawColor(Color.RED))
canvas.drawColor(Color.YELLOW);
复制代码
- 参数是颜色值
- 绘制颜色还有别的方法:
drawRGB(int r, int g, int b)
,drawARGB(int a, int r, int g, int b)
2.画几何图形:圆、矩形、扇形
(1).画圆 drawCircle(float cx, float cy, float radius, Paint paint)
//一共四个圆:1.实心圆 2.空心圆 3.蓝色实心圆 4.线宽为 20 的空心圆
canvas.drawCircle(100,100,100,mPaint);
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(400,100,100,mPaint);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.BLUE);
canvas.drawCircle(100,400,100,mPaint);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(20);
canvas.drawCircle(400,400,100,mPaint);
复制代码
参数分别为:圆心点X坐标,圆心点Y坐标,半径,画笔
(2).画椭圆drawOval(float left, float top, float right, float bottom, Paint paint)
RectF rectF=new RectF(200f,200f,600f,500f);
canvas.drawOval(200,200,600,500,mPaint);
canvas.drawOval(rectF,mPaint);
复制代码
参数分别为:
left
,top
,right
,bottom
,画笔前四个参数也可以替换为一个
RectF
对象
drawOval(RectF oval, Paint paint)
(3).画矩形drawRect(float left, float top, float right, float bottom, Paint paint)
Rect rect=new Rect(200,200,400,400);
RectF rectF=new RectF(200f,200f,400f,400f);
canvas.drawRect(200,200,400,400,mPaint);
canvas.drawRect(rect,mPaint);
canvas.drawRect(rectF,mPaint);
复制代码
参数分别为:
left
,top
,right
,bottom
,画笔
left
和top
决定矩形的起始坐标,right
决定矩形的宽度,bottom
决定矩形的高度前四个参数也可以替换为一个
Rect
或RectF
对象
drawRect(Rect r, Paint paint)
drawRect(RectF rect, Paint paint)
(4).画圆角矩形drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)
,drawRect(RectF rect, float rx, float ry, Paint paint)
canvas.drawRoundRect(200,200,600,400,20,20,mPaint);
复制代码
- 参数分别为:
left
,top
,right
,bottom
,圆角x轴半径,圆角y轴半径,画笔- 前四个参数也可以替换为一个
Rect
或RectF
对象
(5).画扇形drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
RectF rectF=new RectF(380f,200f,780f,500f);
canvas.drawArc(400,200,800,500,-120,110,true,mPaint);
canvas.drawArc(400,250,800,500,0,180,false,mPaint);
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawArc(rectF,-180,50,false,mPaint);
复制代码
参数分别为:
left
,top
,right
,bottom
,开始角度,绘制角度,是否连接到圆心,画笔注意角度问题:X轴方向为0°,顺时针是正角度,逆时针为负角度
注意是否连接到圆心参数:
useCenter
前四个参数也可以替换为一个
RectF
对象
drawArcF(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
画圆、矩形时Paint可以设置什么?
setStyle()
设置画圆的风格:描边->Paint.Style.STROKE()
;填充->`Paint.Style.FILL``setColor()
设置颜色setStrokeWidth()
当style
为Paint.Style.STROKE()
设置描边的宽度
3.画点、线、路径
(1).画点:drawPoint(float x, float y, Paint paint)
float[] mPoints=new float[]{0,0,100,100,100,200,200,100,200,200};
mPaint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawPoint(200,200,mPaint);
mPaint.setStrokeCap(Paint.Cap.SQUARE);
canvas.drawPoint(400,200,mPaint);
canvas.drawPoints(mPoints,mPaint);
canvas.drawPoints(mPoints,2,6,mPaint);
复制代码
参数分别为:起始x轴坐标,起始y轴坐标,画笔
也可以画多个点:
drawPoints(float[] pts, Paint paint)
drawPoints(float[] pts,int offset, int count, Paint paint)
多个点需要传入点的xy坐标的数组,offset指定跳过几个坐标,count是指画几个坐标。无论offset还是count都建议是2的倍数。
利用
Paint
的setStrokeCap
方法设置点的形状,Paint.Cap.ROUND
:圆形;Paint.Cap.SQUARE
,Paint.Cap.BUTT
:方形利用
Paint
的setStrokeWidth
方法设置点的大小
(2).画线:drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
float[] lines=new float[]{0,0,100,100,100,100,200,100,200,200,300,200,200,200,200,300};
canvas.drawLine(100,100,300,300,mPaint);
canvas.drawLines(lines,mPaint);
canvas.drawLines(lines,4,4,mPaint);
复制代码
参数说明:前四个参数分别为起点和终点的xy坐标,最后一个参数为画笔
也可以画多条线:
drawLines(float[] pts, Paint paint)
drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
多条线需要传入多组线的点,基本4个点确定一条线,offset指定跳过几个坐标,count是指画几个坐标。无论offset还是count都建议是4的倍数。
利用
Paint
的setStrokeWidth
方法设置线的宽度
(3).画路径:drawPath(Path path, Paint paint)
//画桃心
Path mPath=new Path();
mPath.addArc(200, 200, 400, 400, -225, 225);
mPath.arcTo(400, 200, 600, 400, -180, 225, false);
mPath.lineTo(400, 542);
canvas.drawPath(mPath,mPaint);
复制代码
- 参数说明:
Path
,画笔Path
类组合了几何图形,线,把这些图形集合起来可以描述更复杂的图形
moveTo()
:Path
默认从当前坐标开始,使用moveTo()
方法可以先移动到指定位置,从这个位置开始addxxx()
:这个方法用来添加子图形,如上所述那些:Circle,Oval,Rect,RountRect,Arc
等,参数可以参考画单独图形的参数xxxTo()
:这个方法用来添加直线,曲线,弧线等。lineTo,arcTo,quadTo,cubicTo
等close()
:这个方法用于封闭图形,从当前位置连接到起点setFillType
:Path
的辅助设置或计算,这个方法只是其中一种常见的(其余的不多做介绍了),用于设置填充方式
EVEN_ODD
:交叉填充,粗暴来说:就是只填充非交集部分。原理就是even-odd rule
奇偶原则:对于平面中的任意一点,对任意一个方向射出一条线,如果与图形相交的点是奇数则认为在图形内,反之则在图形外。只绘制图形内WINDING
(默认值):全填充,原理是non-zero winding rule
,非零环绕原则,对图形的绘制方向有要求。对于平面中的任意一点,对任意一个方向射出一条线,与图形的所有相交点,如果是顺时针则+1,逆时针-1。如果最后结果不为0则认为在图形内部,是要被涂色的区域。反之,则认为在图形外部,不被涂色。INVERSE_EVEN_ODD
,INVERSE_WINDING
这两个是前两个的反色版本
4.还可以画什么???
- 画文字:
drawText(CharSequence text, int start, int end, float x, float y, Paint paint)
- 画图片:
drawPicture(Picture picture, RectF dst)
,drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)