自定义View——drawXXX
前言
既然要自定义View,那么自然少不了各种绘制,既然要绘制,那么自然离不开Canvas和Paint,那么本篇文章就介绍一下,canvas的各种drawXXX方法和Paint一些常用方法。
Android中的坐标系
Android中的坐标系的X轴与传统的坐标系一致,但是Y轴与传统的坐标系不同,方向是相反的。
Paint常用方法
-
Paint.setStyle(Style style) 设置绘制模式
-
Paint.setColor(int color) 设置颜色
-
Paint.setStrokeWidth(float width) 设置线条宽度
-
Paint.setTextSize(float textSize) 设置文字大小
-
Paint.setAntiAlias(boolean aa) 设置抗锯齿开关
抗锯齿关闭与开启 -
Paint.setDither(boolean dither) 设置防抖动开关
防抖动未开启
防抖动开启
onDraw()
以下所有操作均是在onDraw()中进行的,把绘制代码写在 onDraw() 里面,就是自定义绘制最基本的实现。
canvas.drawColor(@ColorInt int color) 颜色填充
在整个绘制区域统一涂上指定的颜色,当然你也可以传入带透明度的颜色,达到遮罩层的效果
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.YELLOW);
}
drawColor
canvas.drawCircle 画圆
canvas.drawCircle(float centerX, float centerY, float radius, Paint paint)
-
centerX,centerY:确定圆心的坐标
-
radius:确定圆的半径
canvas.drawCircle(300f, 300f, 200f, mPaint);
drawCircle
补充
Paint.setColor(int color)改变画笔的颜色
mPaint.setColor(Color.BLUE);
canvas.drawCircle(200f, 400f, 100f, mPaint);
BLUE
Paint.setStyle(Paint.Style style)改变画笔的风格
Style有三种,分别是FILL, STROKE 和 FILL_AND_STROKE。
- FILL:填充模式(默认)
- STROKE:勾边模式
- FILL_AND_STROKE:两种模式一并使用,既画线又填充
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(500f, 100f, 100f, mPaint);
STROKE
Paint.setStrokeWidth(float width)设置线条宽度
mPaint.setStrokeWidth(20f);
canvas.drawCircle(500f, 500f, 100f, mPaint);
setStrokeWidth
canvas.drawRect 画矩形
画矩形有三种方法
- drawRect(RectF rect, Paint paint)
- drawRect(Rect rect, Paint paint)
- drawRect(float left, float top, float right, float bottom, Paint paint)
-
left,top,right,bottom:这4个参数的意思我在下图中标记出来
这里有朋友可能就要问了,Rect和RectF有什么区别?
简单来说,最大的不同就是精度不同,一个传int类型,传float类型,至于其他的不同这里暂时先不说,也用不到。
canvas.drawRect(200f,100f,400f,300f,paint);
等价于
RectF rectF = new RectF(200f,100f,400f,300f);
canvas.drawRect(rectF,paint);
drawRect
canvas.drawPoint 画点
canvas.drawPoint(float x, float y, Paint paint)
-
x,y:圆点的坐标
-
点的大小:paint.setStrokeWidth(width)
-
点的形状:paint.setStrokeCap(cap) ,ROUND圆形,SQUARE或BUTT方形(默认)。
paint.setStrokeWidth(40);
paint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawPoint(100f,100f,paint);
paint.setStrokeCap(Paint.Cap.BUTT);
canvas.drawPoint(600f,300f,paint);
drawPoint
canvas.drawPoints 批量画点
批量画点有两种方法
- canvas.drawPoints(float[] pts, int offset, int count, Paint paint)
- canvas.drawPoints(float[] pts, Paint paint)
-
pts:点的坐标数组
//绘制八个点(50,50)(100,50)(150,50)(200,50)
//(50,100)(100,100)(150,100)(200,100)
float[] pts = {50,50,100,50,150,50,200,50,50,100,100,100,150,100,200,100};
canvas.drawPoints(pts,paint);
drawPoints
-
offset:从数组中的第几个index开始取
-
count:取几个
举个例子,我们传offset为2,count为4,再传offset为1,count为4看看效果
显然这两个点的坐标为(100,50)和(150,50)
offset为2
这两个点的坐标为(50,100)和(50,150)
offset为1
canvas.drawOval 画椭圆
画椭圆有两种方法
- drawOval(RectF rect, Paint paint)
- drawOval(float left, float top, float right, float bottom, Paint paint)
canvas.drawOval(300f,300f,600f,450f,paint);
drawOval
其实我们可以理解为下图 oval.png
当然我们也可以使用Paint.setStyle(Paint.Style style)绘制出空心椭圆,这里就不演示了,参考上面的drawRect()。
canvas.drawLine 画线
canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
-
startX,startY:起始点的坐标
-
stopX,stopY:结束点的坐标
两点确定一条直线。。。,当然我们也可以使用paint.setStrokeWidth()改变线的宽度。
canvas.drawLine(100,100,400,100,paint);
paint.setStrokeWidth(10);
canvas.drawLine(100,300,400,300,paint);
drawLine
canvas.drawLines 批量画线
批量画线有两种方法
- canvas.drawLines(float[] pts, int offset, int count, Paint paint)
- canvas.drawLines(float[] pts, Paint paint)
这里的参数与上面画点是一样的。
//(50,50)(150,50)(100,0)(100,150)(100,50)(50,150)(100,50)(150,150)
float[] pts = {50,50,150,50,100,0,100,150,100,50,50,150,100,50,150,150};
canvas.drawLines(pts,paint);
本来想画个李字的,想了想,点太多了,画个木字算了,哈哈哈,请原谅我懒。。。
drawLines
canvas.drawRoundRect 画圆角矩形
-
rx,ry:圆角的横向半径和纵向半径
画圆角矩形有两种方法
- drawRoundRect(RectF rect, float rx, float ry, Paint paint)
- drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)
canvas.drawRoundRect(200f,300f,600f,500f,20f,20f,paint);
drawRoundRect
canvas.drawArc 绘制弧形或扇形
canvas.drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
-
left,top,right,bottom:还是用来确定绘制位置的
-
startAngle:起始角度
-
sweepAngle:划过的角度
-
useCenter:是否连接到圆心
这里首先我们要确定一个概念,0度在哪里,直接贴图
角度坐标图
RectF rectF = new RectF(300f,200f,500f,400f);
paint.setStyle(Paint.Style.FILL);//填充模式
canvas.drawArc(rectF, -110f, 100f, false, paint);//不连接圆心的填充弧形
canvas.drawArc(rectF,20f,140f,true,paint);//连接圆心的填充扇形
paint.setStyle(Paint.Style.STROKE);//钩边模式
canvas.drawArc(rectF,-160f,40f,false,paint);//不连接圆心的弧形
canvas.drawArc(rectF,170f,20f,true,paint);//连接圆心的扇形
drawArc
canvas.drawBitmap 画 Bitmap
canvas.drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
canvas.drawBitmap(bitmap,20f,20f,paint);
drawBitmap
canvas.drawText 绘制文字
canvas.drawText(String text, float x, float y, Paint paint)
paint.setTextSize(20);
canvas.drawText("LXT",50f,100f,paint);
paint.setTextSize(30);
canvas.drawText("LXT",50f,200f,paint);
paint.setTextSize(40);
canvas.drawText("LXT",50f,300f,paint);
paint.setTextSize(50);
canvas.drawText("LXT",50f,400f,paint);
drawText