一.Canvas简介
Canvas我们可以称之为画布,能够在上面绘制各种东西,是安卓平台2D图形绘制的基础,
源码中关于Canvas的解释:
The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the
pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text,
Bitmap), and a paint (to describe the colors and styles for the drawing).
The Canvas class holds the "draw" calls. To draw something, you need 4 basic components:
A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap),
a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles
for the drawing).
1.保存像素的Bitmap
2.管理绘制请求的Canvas
3.绘画的原始基本元素,例如矩形,线,文字,Bitmap
4.拥有颜色和风格信息的画笔
二.Canvas常用方法介绍
操作类型 | 相关API | 备注 |
---|---|---|
绘制颜色 | drawColor, drawRGB, drawARGB | 使用单一颜色填充整个画布 |
绘制基本形状 | drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc | 依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧 |
绘制图片 | drawBitmap, drawPicture | 绘制位图和图片 |
绘制文本 | drawText, drawPosText, drawTextOnPath | 依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字 |
绘制路径 | drawPath | 绘制路径,绘制贝塞尔曲线时也需要用到该函数 |
顶点操作 | drawVertices, drawBitmapMesh | 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用 |
画布剪裁 | clipPath, clipRect | 设置画布的显示区域 |
画布快照 | save, restore, saveLayerXxx, restoreToCount, getSaveCount | 依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 回滚到指定状态、 获取保存次数 |
画布变换 | translate, scale, rotate, skew | 依次为 位移、缩放、 旋转、错切 |
Matrix(矩阵) | getMatrix, setMatrix, concat | 实际上画布的位移,缩放等操作的都是图像矩阵Matrix, 只不过Matrix比较难以理解和使用,故封装了一些常用的方法。 |
三、Canvas绘制常见图行详解
1.绘制颜色:
绘制颜色是填充整个画布,常用于绘制底色。即View的背景色
canvas.drawColor(Color.BLUE); //绘制蓝色
2.初始化画笔
private void init(){
mPaint = new Paint();
mPaint.setColor(Color.BLUE);//设置画笔颜色
mPaint.setStyle(Paint.Style.FILL);//设置画笔模式为填充
mPaint.setAntiAlias(true);//是否抗锯齿
mPaint.setStrokeWidth(10f); //设置画笔宽度为10px
}
private Paint mPaint;
public MyCoustomView(Context context) {
super(context);
init();
}
public MyCoustomView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyCoustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
画笔创建完之后就可以开始绘制各种图形了
需要指出的是,我们并没有重写onMeasure(),则改view的大小默认是屏幕的大小,关于onMeasure() 我们会放到后面详细讲解
a> 画 点
canvas.drawPoint(100,100,mPaint);//在坐标(100,100)的位置画一个点
canvas.drawPoints(new float[]{ //绘制一组点,坐标位置由float数组指定
500,500,
500,600,
500,700
},mPaint);
b> 划 线
划线的话,里面的参数分别是起点坐标,重点坐标,以及画笔
canvas.drawLine(300,300,500,600,mPaint); // 在坐标(300,300)(500,600)之间绘制一条直线
canvas.drawLines(new float[]{ // 绘制一组线 每四数字(两个点的坐标)确定一条线
100,200,200,200,
100,300,200,300
},mPaint);
c> 画矩形
drawRect(float left, float top, float right, float bottom, @NonNull Paint paint)
- 矩形用两个点来确定他的位置和大小,即用矩形的左上和右下两个点来确定矩形的大小,方法中的两个点的坐标即是矩形的左上右下两个点的坐标
// 第一种
canvas.drawRect(100,100,800,400,mPaint);
// 第二种
mPaint.setColor(Color.GREEN);
Rect rect = new Rect(100,500,800,800);
canvas.drawRect(rect,mPaint);
// 第三种
mPaint.setColor(Color.RED);
RectF rectF = new RectF(100,900,800,1200);
canvas.drawRect(rectF,mPaint);
d> 画圆角矩形
下面简单解析一下圆角矩形的几个必要的参数的意思。
很明显可以看出,第二种方法前四个参数和第一种方法的RectF作用是一样的,都是为了确定一个矩形,最后一个参数Paint是画笔,无需多说,与矩形相比,圆角矩形多出来了两个参数rx 和 ry,这两个参数是干什么的呢?
稍微分析一下,既然是圆角矩形,他的角肯定是圆弧(圆形的一部分),我们一般用什么确定一个圆形呢?
答案是圆心 和 半径,其中圆心用于确定位置,而半径用于确定大小。
由于矩形位置已经确定,所以其边角位置也是确定的,那么确定位置的参数就可以省略,只需要用半径就能描述一个圆弧了。
但是,半径只需要一个参数,但这里怎么会有两个呢?
好吧,让你发现了,这里圆角矩形的角实际上不是一个正圆的圆弧,而是椭圆的圆弧,这里的两个参数实际上是椭圆的两个半径,他们看起来个如下图:
// 第一种
mPaint.setColor(Color.parseColor("#C7EDCC"));
RectF rectF = new RectF(100,100,800,400);
canvas.drawRoundRect(rectF,30,30,mPaint);
// 第二种
mPaint.setColor(Color.parseColor("#FF00FF"));
canvas.drawRoundRect(100,500,800,800,30,30,mPaint);
e>画椭圆
相对于绘制圆角矩形,绘制椭圆就简单的多了,因为他只需要一个矩形矩形作为参数:
// 第一种
mPaint.setColor(Color.parseColor("#FF1493"));
RectF rectF = new RectF(100,100,800,400);
canvas.drawOval(rectF,mPaint);
//第二种
mPaint.setColor(Color.parseColor("#4B0082"));
canvas.drawOval(100,600,800,900,mPaint);
f>画 圆
- drawCircle(float cx, float cy, float radius, @NonNull Paint paint)
radius
: 半径
cx
: 圆心的x
坐标
cy
: 圆心的y
坐标
使用的时候需要考虑圆心和半径
mPaint.setColor(Color.parseColor("#40E0D0"));
canvas.drawCircle(getWidth()/2,getHeight()/2,400,mPaint);
g>画 弧
drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint)
float startAngle
开始绘制的角度float sweepAngle
扇形扫过的角度,并不是停止时的角度。停止角度 =startAngle
+sweepAngle
boolean useCenter
ture就是有焦点圆心 , false 没有
1.以矩形为背景画弧形
/*
第一种
*/
RectF rectF = new RectF(100,100,800,400);
// 绘制背景矩形
mPaint.setColor(Color.parseColor("#008080"));
canvas.drawRect(rectF,mPaint);
// 绘制圆弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF,0,90,false,mPaint);//参数为false的时候
/*
第二种
*/
RectF rectF2 = new RectF(100,500,800,900);
// 绘制背景矩形
mPaint.setColor(Color.parseColor("#008080"));
canvas.drawRect(rectF2,mPaint);
// 绘制圆弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF2,0,60,true,mPaint);//参数为true的时候
RectF rectF2 = new RectF(100,100,800,800);
// 绘制背景矩形
mPaint.setColor(Color.parseColor("#008080"));
canvas.drawRect(rectF2,mPaint);
// 绘制圆弧
mPaint.setColor(Color.parseColor("#EE82EE"));
canvas.drawArc(rectF2,0,60,ture,mPaint);
mPaint.setColor(Color.parseColor("#00FFFF"));
canvas.drawArc(rectF2,60,30,true,mPaint);
RectF rectF2 = new RectF(100,100,800,800);
// 绘制背景矩形
mPaint.setColor(Color.parseColor("#008080"));
canvas.drawRect(rectF2,mPaint);
// 绘制圆弧
mPaint.setColor(Color.parseColor("#EE82EE"));
canvas.drawArc(rectF2,0,60,false,mPaint);
mPaint.setColor(Color.parseColor("#00FFFF"));
canvas.drawArc(rectF2,60,30,false,mPaint);