Canvas 顾名思义画布,其成员函数save()、restore()分别为保存恢复状态。
save():保存当前的Matrix和clip放在私有栈里面。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作,而不会影响到save之前的操作,也就是说你旋转了,但是save之前画出来的东西不会旋转。放缩,平移、错切、裁剪也是如此。
restore():和save()是对应起来的,他是用来在之前save过的画布上清楚掉save之后所有的修改。也就是save之后的一些操作对save之前的操作没有影响。
private void drawSaveAndRestore(Canvas canvas) {
int w = getMeasuredWidth();
int h = getMeasuredHeight();
mPaint.setColor(Color.RED);
//在(20,20)坐标处画一个半径为20的圆
canvas.drawCircle(20, 20, 20, mPaint);
mPaint.setColor(Color.BLUE);
//给整个画布画一个框
canvas.drawRect(0,0,w,h,mPaint);
mPaint.setColor(Color.GREEN);
//保存之前的状态
canvas.save();
//以画布中心旋转90度,这个时候整个坐标系都旋转了90度
canvas.rotate(90, w / 2, h / 2);
//画三条线,以(w/2,0)处分别画左中右三条线,画一个向上的箭头,因为已经旋转了90度了,其实画的是向右的箭头
canvas.drawLine(w / 2, 0, 0, h / 2, mPaint);
canvas.drawLine(w / 2, 0, w / 2, h, mPaint);
canvas.drawLine(w / 2, 0, w, h / 2, mPaint);
// canvas.restore();
mPaint.setColor(Color.parseColor("#ffffff00"));
//在(30,30)画一个半径为30的圆
canvas.drawCircle(30, 30, 30, mPaint);
}
这里我们没有采用restore的方法进行恢复操作,效果如下:
此时对应的坐标系图是,所以黄色的圆圈自然是画在右上角
因为没有采用restore进行坐标系恢复,最后一个画圆是旋转之后的坐标系画的,这个坐标系的原点是在右上角。如果我们加上canvas.restore()这句话的注释取消掉之后看一下效果。
此时对应的坐标系图是,所以黄色的圆圈画在左上角
现在是在我们理解的坐标系内画出了一个半径为30的圆。所以restore()方法可以认为是恢复坐标系。坐标系的变换操作只对save()和restore()之间的操作有效,比如说旋转之后,在没有调用restore()之前都是以右上角为坐标系原点。而restore()之后又旋转回来了。
private void drawSaveAndRestore(Canvas canvas) {
int w = getMeasuredWidth();
int h = getMeasuredHeight();
mPaint.setColor(Color.RED);
//在(20,20)坐标处画一个半径为20的圆
canvas.drawCircle(20, 20, 20, mPaint);
mPaint.setColor(Color.BLUE);
//给整个画布画一个框
canvas.drawRect(0,0,w,h,mPaint);
mPaint.setColor(Color.GREEN);
//保存之前的状态
canvas.save();
//将坐标系平移到(100,100)的位置
canvas.translate(100, 100);
//画三条线
canvas.drawLine(w / 2, 0, 0, h / 2, mPaint);
canvas.drawLine(w / 2, 0, w / 2, h, mPaint);
canvas.drawLine(w / 2, 0, w, h / 2, mPaint);
// canvas.restore();
mPaint.setColor(Color.parseColor("#ffffff00"));
canvas.drawCircle(30, 30, 30, mPaint);
}
效果图:(PS:坐标系是我自己画的)
取消掉restore()的注释之后,坐标系恢复,画出的黄色原点在左上角。
缩放,向缩放这种就不是恢复坐标系了,而是恢复缩放状态。
效果图如下:
没有使用restore
使用了restore
扭曲:
没有使用restore
使用了restore
其实都一样啦,对于旋转平移来说,save和restore可以理解为坐标系的保存与恢复,位于缩放、扭曲等来说可以认为缩放状态和扭曲状态的保存和恢复。都是保存一下做一些操作,然后再恢复为保存之前的状态。但是save和restore之间的一些操作保持是变换(旋转、平移等)后操作的效果。
下面这篇文章对clipRect操作的save()入栈,restore()出栈过程讲的非常清楚。
http://blog.csdn.net/harvic880925/article/details/39080931