在介绍这两个方法之前,需要先对Canvas的坐标了解。Canvas的坐标默认和屏幕的坐标系相同,如下图

在对Canvas做操作时都是基于该套坐标系完成,但是我们在使用Canvas的变换(平移、旋转、缩放)的方法时会使Canvas的坐标系发生变化,可能与屏幕坐标就不相同了,但是Canvas的绘图切割等操作还是基于Canvas的坐标系。下面通过一段代码来演示Canvas坐标变换后的行为。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.RED);
canvas.drawRect(0, 0, 200, 200, mPaint);
canvas.translate(100, 100);
mPaint.setColor(Color.BLUE);
canvas.drawRect(0, 0, 200, 200, mPaint);
}
运行效果如图:

根据效果图可以很清晰的看到translate使Canvas坐标向右下各移动了100px。
为了Canvas状态的还原,Canvas提供了Restore方法,但这样还不人性化,因为有时例如我们在translate操作后,然后又做了旋转操作,此时我们只想回到平移操作后的状态继续进行放大缩小操作,聪明的Google引入了栈的方式来管理Canvas的状态,入栈就是save操作,出栈就是restore操作,与你想象不同的一点是这个出入栈期间绘制的内容依然原样绘制在画布上。
Canvas的save方法和restore方法
-
save
save api
保存当前矩阵信息和剪切信息到私有栈。其实旋转、平移、放大、错切等操作都是通过矩阵来完成的,故保存矩阵信息。
-
restore
restore api
调用restore方法可以清除Canvas的上一次save之后的平移、放大等和剪切的状态(只是清除状态,绘制的内容依然原样保持)
-
restoreToCount
restoreToCount api
恢复到第几次save时的状态
主要注意的是如果调用restore方法次数多余save方法调用次数时会报错。
老规矩,小示例带你深入理解,对上面代码进行小改动
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.RED);
canvas.drawRect(0, 0, 200, 200, mPaint);
canvas.save();
canvas.translate(100, 100);
mPaint.setColor(Color.BLUE);
canvas.drawRect(0, 0, 200, 200, mPaint);
canvas.restore();
mPaint.setColor(Color.GREEN);
canvas.drawRect(0, 300, 200, 500, mPaint);
}
示例效果:

可以看到在执行translate前先save,在绘制最后一个绿色矩形时要清除刚才的平移效果,只需调用restore方法即可让Canvas恢复初始美貌,坐标0点又回到了上一次的屏幕左上角。
网友评论