canvas的save,restore方法的使用理解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tingfengzheshuo/article/details/51706174
笔者最近在研究android上的动画机制,最近有点偏题,偏到View draw过程了。。。
view的draw中经常用到canvas的save方法和restore方法。网上找的一些文章讲的都不透彻,最后是自己发了一些时间研究才了解方法的作用,并且学习到了其它的一些细节知识。
先给出总结:save方法是把canvas当前的坐标系特征数据保存在一个stack中的方法,restore方法是从这个stack中移除顶层的数据的方法。那这个坐标系特征数据指的是哪些数据呢?看看save方法的google官方解释
/**
* Saves the current matrix and clip onto a private stack. Subsequent
* calls to translate,scale,rotate,skew,concat or clipRect,clipPath
* will all operate as usual, but when the balancing call to restore()
* is made, those calls will be forgotten, and the settings that existed
* before the save() will be reinstated.
*
* @return The value to pass to restoreToCount() to balance this save()
*/
这个方法解释中详细说明了保存的数据,
translate,scale,rotate,skew,concat or clipRect,clipPath
移动,缩放,旋转,倾斜,串联或者偏移之类的数据,这个数据时被放在一个私有化的stack中,当调用restore方法后,对这些对象的操作就会移除,调用一次restore方法,canvas坐标系特征这是还原到上一次调用save方法时保存的数据。比如说,你对canvas对象做了一次90度旋转,然后调用了save方法,然后又把canvas对象放大为2倍,又掉用了save方法,那么你在调用restore方法,那么canvas的坐标系特征就是被转了90度的样子,如果再调用一次resotore方法,那么canvas就在初始化时的位置了。
注意点:
1,save和resotre只是控制坐标系特征的,restore只会把坐标系特征还原,不会清除save之后绘制的元素。
2,对canvas做旋转缩放之类的操作,不会对坐标系本身产生影响,坐标原点还是在view的左上角。
3,不管做了多少次旋转,缩放之类的操作,就算你save了N多次之后都没有调用restore方法,canvas最终绘制在view上坐标系数据都是要还原到初始状态的,比如说,你没有做任何save之前,在canvas上绘制了一个向上的箭头,然后把canvas顺时针旋转90度,那么箭头此时应该是向右的,然后你调用save方法,onDraw方法到此为止。view显示在屏幕上你会发现箭头还是向上的!不管你在onDraw中旋转了多少次,save的多少次,最终显示的图像箭头就是向上的。
4,restore的方法解释下:
/**
* This call balances a previous call to save(), and is used to remove all
* modifications to the matrix/clip state since the last save call. It is
* an error to call restore() more times than save() was called.
*/
其中提到,如果resotre调用次数多于save方法次数,就会报错。但是在实际操作中并不是这样,如果没有调用过save方法就调用restore方法会报错,报错为 java.lang.IllegalArgumentException: Underflow in restoreToCount, 但是如果调用过save方法后再调用retore,restore方法次数比save方法多,也不会报错,我的测试环境是android5.1.1。

想上一些自己验证时写的代码,但是发现有点麻烦,并且代码中很多是绕弯路时写的代码,有效代码其实就那样,验证的东西上面已经说清了了,就不上了。

猜你喜欢

转载自blog.csdn.net/tingfengzheshuo/article/details/51706174