一、简述
- 本文主要包含Canvas(画布)与Paint(画笔),详细介绍了相关api。
- canvas的所有的单位均为像素,下文demo仅适配分辨率1080*1920的屏幕。
- 关于view基础及dp与px的转换可以看View位置及触摸事件这篇文章。
- 请注意一个问题:如果在onDraw方法中绘制的,但是onDraw方法没有走,请在构造函数中添加
setWillNotDraw(false);
。解释:设置view是否更改,如果开发者用自定义的view,重写onDraw()应该将调用此方法设置为false,这样程序会调用自定义的布局。
二、Paint(画笔)
- 创建画笔:
Paint p = new Paint();
- 给画笔设置颜色:
p.setColor(Color.RED);
- 设置绘制的文字大小(单位是px):
p.setTextSize(60);
- 设置画笔的锯齿效果(true是去除):
p.setAntiAlias(true);
- 设置风格:
p.setStyle(Paint.Style.FILL);
,默认样式就是填充,常用的还有设置空心Paint.Style.STROKE
- 重置画笔:
p.reset();
- 设置渐变色:使用
Shader
对象Shader
类专门用来渲染图像以及一些几何图形,请看下面的代码及注释:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/**
* Shader类专门用来渲染图像以及一些几何图形
* LinearGradient是Shader的子类,用来进行梯度渲染
* Shader类的使用,需要先构建Shader对象,然后通过Paint的setShader方法设置渲染对象,
* 然后设置渲染对象,然后再绘制时使用这个Paint对象即可。
*
* @param x0 起始的x坐标
* @param y0 起始的y坐标
* @param x1 结束的x坐标
* @param y1 结束的y坐标
* @param colors 颜色数组
* @param positions 这个也是一个数组用来指定颜色数组的相对位置 如果为null 就沿坡度线均匀分布
* @param tile 渲染模式
*/
Shader mShader = new LinearGradient(0, 0, 100, 100,
new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,
Color.LTGRAY}, null, Shader.TileMode.REPEAT);
- 设置Shader:
p.setShader(mShader);
- 清除Shader:我尝试使用
p.setShader(null);
可以取消,并且没有影响,当然,也可以使用重置画笔p.reset();
三、Canvas(画布)
注意:canvas是onDraw方法中的,我是直接继承布局在onDraw方法中画的,没有使用SurfaceView或Bitmap
绘制文字
1
2
3
4
5
6
7/**
* @param text 文本
* @param x 水平方向起点
* @param y 竖直方向的文字底部
* @param paint 画笔
*/
canvas.drawText("画圆:", 50, 100, p);画圆
1
2
3
4
5
6
7
8/**
* 画圆
* @param cx 圆心x坐标
* @param cy 圆心y坐标
* @param radius 半径
* @param paint 画笔
*/
canvas.drawCircle(300, 80, 50, p);画线条
1
2
3
4
5
6
7
8
9/**
* 画线条
* @param startX 起点x坐标
* @param startX 起点y坐标
* @param stopX 终点x坐标
* @param stopY 终点y坐标
* @param paint 画笔
*/
canvas.drawLine(500, 225, 700, 225, p);绘制矩形
1
2
3
4
5
6
7
8
9/**
* 绘制矩形(两点确定位置,左上角与右下角)
* @param left 左上角x
* @param top 左上角y
* @param right 右下角x
* @param bottom 右下角y
* @param paint:绘制时所使用的画笔。
*/
canvas.drawRect(300, 350, 500, 400, p);画点
1
2
3
4
5
6
7/**
* x,y坐标
*/
//画一个点
canvas.drawPoint(500, 1200, p);
//画多个点
canvas.drawPoints(new float[]{600, 1200, 650, 1250, 700, 1200}, p);画图片(贴图)
1
2
3
4
5
6
7
8Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
/**
* @param bitmap The bitmap to be drawn
* @param left 左上角x坐标
* @param top 左上角y坐标
* @param paint 画笔
*/
canvas.drawBitmap(bitmap, 360, 1300, p);画弧线、扇形,椭圆
使用到了
RectF
,先介绍下这个1
2
3
4
5
6
7
8/**
* 表示一块矩形区域(left <= right and top <= bottom)
* @param left 左上角x
* @param top 左上角y
* @param right 右下角x
* @param bottom 右下角y
*/
RectF oval1 = new RectF(800, 50, 900, 100);绘制
1
2
3
4
5
6
7
8
9
10
11
12
13
14/**
* oval:圆弧所在的RectF对象。
* startAngle:圆弧的起始角度。
* sweepAngle:圆弧的角度。
* useCenter:是否显示半径连线,true表示显示圆弧与圆心的半径连线,false表示不显示。
* paint:绘制时所使用的画笔。
*/
// 画弧线(画弧线是要同时设置画笔样式为Paint.Style.STROKE)
canvas.drawArc(oval1, 180, 180, false, p);
// 画扇形
canvas.drawArc(oval2, 200, 130, true, p);
// 画椭圆
oval2.set(650, 450, 900, 650);
canvas.drawOval(oval2, p);扩展:画笑脸
1
2
3
4
5
6
7
8
9
10
11
12/**
* 画笑脸方法:创建一个RectF区域(这个区域仅容纳第一笔)画第一笔,
* 第一笔绘制完成修改RectF区域画第二笔,依次类推
*/
canvas.drawArc(oval1, 180, 180, false, p);//小弧形
/**
* 设置RectF布局,参数与创建RectF相同
*/
oval1.set(950, 50, 1050, 100);
canvas.drawArc(oval1, 180, 180, false, p);//小弧形
oval1.set(850, 100, 1000, 200);
canvas.drawArc(oval1, 0, 180, false, p);//小弧形
画圆角矩形
1
2
3RectF oval3 = new RectF(500, 880, 700, 1000);// 设置个新的长方形
//第二个参数是x半径,第三个参数是y半径
canvas.drawRoundRect(oval3, 15, 15, p);画多边形与贝塞尔曲线
依旧先介绍下用到的类
Path
(ps:此处感谢百度翻译):路径类封装的复合(多个轮廓)几何路径组成的直线段,二次曲线,三次曲线。它可以绘制画布上绘制路径(路径、油漆),要么填充或抚摸(根据油漆的风格),也可以用于裁剪或绘画路径上的文本。画三角形,多边形的画法跟三角形是一样的
1
2
3
4
5
6Path path = new Path();
path.moveTo(500, 750);// 此点为多边形的起点
path.lineTo(400, 850);
path.lineTo(600, 850);
path.close(); // 使这些点构成封闭的多边形
canvas.drawPath(path, p);画贝塞尔曲线:
1
2
3
4
5
6Path path2 = new Path();
path2.moveTo(500, 1050);//设置Path的起点
//设置贝塞尔曲线的控制点坐标和终点坐标
path2.quadTo(600, 950, 700, 1050);
path2.quadTo(800, 1150, 900, 1050);
canvas.drawPath(path2, p);