一、简介
Canvas即画布,在自定义View中常用到,它可以通过直接new Canvas()或者new Canvas(Bitmap bitmap)初始化,但我们在使用过程中更多的是通过onDraw(Canvas canvas)得到Canvas对象。
我这里大概将Canvas的功能分为三类
1、绘制各种形状或线条,有如下方法:
drawARGB、drawARC、drawBitmap、drawCircle、drawColor、drawLine、drawOval和drawPath等方法。
2、各种变换操作,如平移、缩放、旋转、倾斜和切割等。
3、状态的保存和恢复。
绘制各种形状和线条相关的方法不在这里讲述,我们主要讲第二三类,在里面也会涉及到绘制相关的内容。
二、变换操作
1、平移
private Paint mPaint;
public TransformView(Context context) {
this(context, null);
}
public TransformView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public TransformView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(4);
mPaint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//平移
//先画一个矩形
Rect rect = new Rect(0, 0, 400, 400);
canvas.drawRect(rect, mPaint);
//将画布平移到位置(100, 100)
canvas.translate(100, 100);
//更换颜色后再画一个矩形
mPaint.setColor(Color.BLUE);
canvas.drawRect(rect, mPaint);
//从平移后的位置划线
mPaint.setColor(Color.GREEN);
canvas.drawLine(0, 0, 400, 400, mPaint);
}
首先在构造方法中初始化了一个画笔,颜色设置成红色,然后在onDraw方法中先画了一个矩形,注意原点(0, 0)的位置在右上角,往右是X轴的正方向,往下是Y轴的正方向。然后将画布移到(100, 100)的位置,此时画布的原点就在(100, 100)位置了,移动后右画了一个矩形,最后画了一根直线,效果如下:
2、缩放
//缩放
Rect rect = new Rect(200, 200, 400, 400);
canvas.drawRect(rect, mPaint);
//整个画布及尺寸都缩小0.5倍
//canvas.scale(0.5f, 0.5f);
//整个画布及尺寸都缩小0.5倍,再从坐标(200, 200)处重新绘制
canvas.scale(0.5f, 0.5f, 200, 200);
mPaint.setColor(Color.GRAY);
canvas.drawRect(rect, mPaint);
缩放操作有两个方法scale(sx, sy)和scale(sx, sy, px, py),第一个方法的参数只有xy方向的缩放尺寸,第二个除了xy方向的缩放尺寸外px和py表示缩放后以该点为原点重新绘制。效果如下:
3、旋转
//旋转
Rect rect = new Rect(400, 400, 900, 900);
canvas.drawRect(rect, mPaint);
//以px、py为原点旋转
canvas.rotate(45, 400, 400);
mPaint.setColor(Color.BLUE);
canvas.drawRect(400, 400, 900, 900, mPaint);
首先绘制一个红色的矩形,然后以px、py(400, 400)为原点旋转45度,再绘制一个蓝色的矩形,效果如下:
4、倾斜
//倾斜
Rect rect = new Rect(0, 0, 400, 400);
canvas.drawRect(rect, mPaint);
//x方向上倾斜45度
canvas.skew(1.0f, 0);
mPaint.setColor(Color.BLUE);
canvas.drawRect(rect, mPaint);
skew(sx, sy),sx表示在X轴方向倾斜,sy表示在Y轴方向倾斜,1.0f是由正切函数tan A = 对边 / 邻边得到,如下图:
效果如下:
5、切割
//切割
Rect rect = new Rect(0, 0, 400, 400);
canvas.drawRect(rect, mPaint);
canvas.clipRect(100, 100, 300, 300);
mPaint.setColor(Color.GREEN);
//只在切割后的区域内绘制有效
canvas.drawLine(100, 100, 300, 300, mPaint);
首先绘制一个矩形,然后在矩形里面将一部分区域切割出来,最后在切割的区别画一条直线,如果划线的地方不在切割区域内,则无法正常显示,效果如下:
6、矩阵
//矩阵
Rect rect = new Rect(0, 0, 400, 400);
canvas.drawRect(rect, mPaint);
Matrix matrix = new Matrix();
//平移
matrix.setTranslate(50, 50);
//旋转
//matrix.setRotate(45);
canvas.setMatrix(matrix);
mPaint.setColor(Color.GREEN);
canvas.drawRect(rect, mPaint);
通过Matrix可以实现以上5种操作,如平移、旋转等,效果如下:
三、状态的保存和恢复
Rect rect = new Rect(100, 100, 400, 400);
canvas.drawRect(rect, mPaint);
canvas.save();
//在平移前保存状态
canvas.translate(100, 100);
mPaint.setColor(Color.BLACK);
canvas.drawRect(rect, mPaint);
//恢复到平移前的状态
canvas.restore();
//在最初的状态画线
mPaint.setColor(Color.BLUE);
canvas.drawLine(0, 0, 600, 600, mPaint);
效果如下:
首先绘制了一个红色的矩形,此时保存了一个状态,然后将画布移动到(100, 100)位置,再绘制一个黑色的矩形,注意绘制两个矩形的参数都相同,最后恢复画布到初始状态,绘制一条蓝色的直线。
为什么需要状态的保存和恢复,比如我们做了一些上面讲的平移、缩放、旋转等操作后,如果想绘制下一个图形时是在以上操作之前的状态绘制,那么我们需要执行一个反向的操作,比如:刚开始执行了setTranslate(100, 100),使画布移动了以(100,100)为原点的位置,这时我又想在最初的原点(0, 0)绘制一条直线,那么我们需要反向执行setTranslate(0, 0)才行,如果是一次这种操作还好,但是多次执行移动、缩放、旋转等操作,再回到某个初始状态就比较麻烦了。
canvas.save()一般在执行变换前调用,保存好状态,canvas.restore()是在我们想回到某一状态时调用,restore与save是成对使用的,还有一个方法是canvas.restoreToCount(int savaCount),savaCount这个值是我们调用save方法时会返回的,restoreToCount表示我想恢复到哪次保存的状态,只需要传入其保存时对应的savaCount即可。
关于Canvas大概就讲到这里,希望能帮助到大家,谢谢!