Canvas详解
绘制几何图形,文本,位图等
- 在指定坐标绘制位图
public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
super.drawBitmap(bitmap, left, top, paint);
}
- 根据给定的起始点和结束点绘制连线
public void drawLine(float startX, float startY, float stopX, float stopY,
@NonNull Paint paint) {
super.drawLine(startX, startY, stopX, stopY, paint);
}
- 根据指定的path绘制连线
public void drawPath(@NonNull Path path, @NonNull Paint paint) {
super.drawPath(path, paint);
}
- 根据指定的坐标绘制点
public void drawPoint(float x, float y, @NonNull Paint paint) {
super.drawPoint(x, y, paint);
}
- 根据给定的坐标绘制文字
public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
super.drawText(text, x, y, paint);
}
绘制位置、形状变换等
- 平移操作translate
canvas.drawRect(0,0,500,500,mPaint);
canvas.translate(50,50);
mPaint.setColor(Color.BLUE);
canvas.drawRect(0,0,500,500,mPaint);
- 缩放操作scale
canvas.drawRect(200,200,700,700,mPaint);
canvas.scale(0.5f,0.5f);
mPaint.setColor(Color.BLUE);
canvas.drawRect(200,200,700,700,mPaint);
其中四个参数的方法为:
canvas.drawRect(200,200,700,700,mPaint);
canvas.scale(0.5f,0.5f,200,200);
//等同于 在四位参数的源码中为
// translate(px, py);
// scale(sx, sy);
// translate(-px, -py);
mPaint.setColor(Color.BLUE);
canvas.drawRect(200,200,700,700,mPaint);
其中四个参数的方法中,后2个参数进行了位移操作。
- 旋转操作rotate
canvas.drawRect(300,300,600,600,mPaint);
//rotate旋转默认为从坐标的0,0位置开始的,想在原图形上旋转需要平移坐标原点至原图形位置
canvas.rotate(45,450,450); px,py为旋转中心位置坐标
mPaint.setColor(Color.BLUE);
canvas.drawRect(300,300,600,600,mPaint);
- 倾斜操作skew
canvas.drawRect(0,0,400,400,mPaint);
//此方法以tan的对边比临边的角度比值进行倾斜
canvas.skew(1,0); //在x轴方向倾斜45度,y轴逆时针旋转45度
//canvas.skew(0,1); //在y轴方向倾斜45度,x轴顺时针旋转45度
mPaint.setColor(Color.BLUE);
canvas.drawRect(0,0,400,400,mPaint);
- 切割操作,参数指定区域内可以继续绘制clipXXX
canvas.drawRect(200,200,700,700,mPaint);
mPaint.setColor(Color.BLUE);
canvas.drawRect(200,800,700,1300,mPaint);
//画布裁剪的部分,为一个200,200,700,700的矩形部分,只能在这一部分进行绘制,其他部分绘制不显示
canvas.clipRect(200,200,700,700);
//超出裁剪区域,无法绘制
canvas.drawCircle(200,800,100,mPaint);
//部分在绘制区域,显示部分
canvas.drawCircle(300,300,300,mPaint);
//完全在绘制区域,全部显示
canvas.drawCircle(400,400,100,mPaint);
- 反向切割操作,参数指定区域内不可以继续绘制clipOutXXX
canvas.drawRect(200, 200, 700, 700, mPaint);
mPaint.setColor(Color.BLUE);
canvas.drawRect(200, 800, 700, 1300, mPaint);
//画布裁剪的部分,为一个200,200,700,700的矩形部分,这一部分不能绘制,只能在这一部分之外的区域进行绘制
canvas.clipOutRect(200, 200, 700, 700);
//裁剪区域,无法绘制
canvas.drawCircle(200, 800, 100, mPaint);
//部分在裁剪区域,显示部分
canvas.drawCircle(300, 300, 300, mPaint);
//完全在绘制区域之外,全部显示
canvas.drawCircle(400, 400, 100, mPaint);
- 可通过matrix实现平移,缩放,旋转等操作setMatrix
canvas.drawRect(0,0,500,500,mPaint);
Matrix matrix = new Matrix();
//移动
//matrix.setTranslate(50,50);
//旋转45度
matrix.setRotate(45);
//缩放
//matrix.setScale(0.5f,0.5f);
canvas.setMatrix(matrix);
mPaint.setColor(Color.BLUE);
canvas.drawRect(0,0,500,500,mPaint);
状态保存和恢复
canvas调用各种translate等变换操作后,后续的操作都是基于变换后的canvas,都会受到影响,对于后续操作不方便。Canvas提供了save,saveLayer,saveLayerAlpha,restore,restoreToCount来保存和恢复状态。
- 通过save和restore restoreToCount保存和恢复状态
canvas.drawRect(0,0,500,500,mPaint);
//位移后画布移动 保存状态
canvas.save();
canvas.translate(50,50);
mPaint.setColor(Color.BLUE);
canvas.drawRect(0,0,500,500,mPaint);
//再次调整画布
canvas.save();
canvas.translate(100,100);
mPaint.setColor(Color.GREEN);
canvas.drawRect(0,0,500,500,mPaint);
//调用save时将其存放的栈中,每调用一次restore释放一个save,返回到上一个状态位置
canvas.restore();
mPaint.setColor(Color.BLUE);
canvas.drawLine(0,0,700,700,mPaint);
//再次释放
canvas.restore();
mPaint.setColor(Color.RED);
canvas.drawLine(0,0,500,900,mPaint);
也可以调用restoreToCount返回到指定的画布位置状态
//调用restoreToCount返回到改保存画布的位置,将此位置之上存在的所有栈全部剔除
canvas.restoreToCount(saveOne);
mPaint.setColor(Color.RED);
canvas.drawLine(0,0,500,900,mPaint);
- 通过离屏绘制进行恢复。即先离屏将其绘制完毕,再将界面添加到画布上(此方法可以指定离屏绘制的画布大小)
canvas.drawRect(200,200,700,700,mPaint);
//离屏绘制区域为0,0,700,700的长方形区域
int layerId = canvas.saveLayer(0,0,700,700,mPaint);
mPaint.setColor(Color.BLUE);
Matrix matrix = new Matrix();
//画布原点平移100,100
matrix.setTranslate(100,100);
canvas.setMatrix(matrix);
//由于离屏绘制区域为0,0,700,700,且画布平移了100,100,所以新画的矩形0,0,700,700不能完全展示完毕
canvas.drawRect(0,0,700,700,mPaint);
//恢复之前的状态
canvas.restoreToCount(layerId);
mPaint.setColor(Color.RED);
canvas.drawRect(0,0,100,100,mPaint);