首先canvas的drawXXX方法就不去细说了,本文只针对canvas状态的变换、保存和复位。
Canvas与View
这里要理解的是Canvas和View的关系,Canvas就是附在View的整个表面的(注意,View并不相当于整个屏幕,View有自己的大小,因此下面所有的图形都是基于View而不是整个屏幕)
Canvas理解:Canvas内部有Matrix和Clip的状态记录,当调用一次translate、rotate、skew、scale,Canvas都会让内部的矩阵Matrix做相应的变换(平移变换、旋转、斜切、缩放),当调用canvas.clipXXX方法时,会改变Canvas内部的Clip的状态。如果在canvas内部的Matrix或Clip的状态发生了改变之后,再调用canvas.drawXXX方法时就会将你要绘制的图形进行相应的Matrix转换。而Canvas还有save方法和restore方法,其实Canvas内部有一个私有的栈,用来存储Matrix和Clip的状态的,当你调用一次save,栈中就会插入一个当前的Matrix和Clip状态,调用restore就会弹出栈顶的Matrix和Clip状态。下面会用通俗点的方式来理解canvas的这些方法。
Canvas的translate、rotate、skew、scale方法
我们先要知道画布与图层的关系,我们可以这么理解,canvas就是View本身,canvas并不会平移、缩放等变换,当canvas每调用一次translate、rotate、skew、scale方法的时候,都会创建一个新的图层,进行变换的只是图层的平移、缩放等,之后的draw方法都会在这个新的图层上绘画。
1、translate方法
使用:
canvas.translate(float dx, float dy);//x轴平移dx,y轴平移dy。
理解:
当canvas调用一次translate方法时,会在平移后的位置创建一个图层,之后的draw方法都在这个图层上绘画,并按照此图层的坐标系。
例:
@Override
protected void onDraw(Canvas canvas) {
//onDraw中创建对象,仅做演示
Paint paint = createPaint(Color.BLUE);//创建一个蓝色的画笔
Rect rect = new Rect(0, 0, 200, 200);//创建一个长宽都是200的矩形,左上角的坐标为(0,0)
canvas.drawRect(rect, paint);//画矩形
canvas.translate(100,100);//按x轴平移100,y轴平移100
canvas.drawRect(rect, paint);//再画矩形
canvas.drawRect(new Rect(10,10,150,150), paint);//再画矩形
}
/**
* 创建一个画笔
*/
private Paint createPaint(int color) {
Paint paint = new Paint();
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
return paint;
}
运行结果(这里我让该View占满整个屏幕的):
2、 rotate方法
使用:
canvas.rotate(float degrees);//以当前图层的原点为旋转中心旋转degrees角度。
canvas.rotate(float degrees, float px, float py);//以当前图层的(px,py)的点为旋转中心旋转degrees角度。
理解:
当canvas调用一次rotate方法时,会在旋转后的位置创建一个图层。之后的draw方法都在这个图层上绘画,并按照此图层的坐标系。
例:
@Override
protected void onDraw(Canvas canvas) {
//onDraw中创建对象,仅做演示
Rect rect = new Rect(0, 0, 200, 200);//创建一个长宽都是200的矩形,左上角的坐标为(0,0)
canvas.drawRect(rect, createPaint(Color.BLUE));//画矩形
canvas.rotate(30);//以图层原点旋转30°
canvas.drawRect(rect, createPaint(Color.RED));//再画矩形
canvas.drawRect(new Rect(10, 10, 150, 150), createPaint(Color.RED));//再画矩形
}
/**
* 创建一个画笔
*/
private Paint createPaint(int color) {
Paint paint = new Paint();
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
return paint;
}
这次的旋转中心不是