标签:
前言:
有些话说得坦白
就会变成感慨
有些事总想不开
难免有太多无奈
这一路走来
梦想从未更改
相信真心的付出
就能够活得精彩
把头抬起来
拍拍身上的尘埃
坚守心底的真爱
勇敢相信未来
——巫启贤《相信未来》
系列文章:
Android自定义控件三部曲文章索引:http://blog.csdn.net/harvic880925/article/details/50995268
public int save() public int save(int saveFlags) public int saveLayer(RectF bounds, Paint paint, int saveFlags) public int saveLayer(float left, float top, float right, float bottom,Paint paint, int saveFlags) public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) public int saveLayerAlpha(float left, float top, float right, float bottom,int alpha, int saveFlags)这段我们先关注前四个,save的两个函数和saveLayer的两个函数;我们知道他们两个不同之处在于saveLayer会新建一个画布,而save函数则不会新建画布;它们都具有Flag标识,这些Flag标识的意义和使用范围如下:
FLAG | 意义 | 适用范围 |
---|---|---|
ALL_SAVE_FLAG | 保存所有的标识 | save()、saveLayer() |
MATRIX_SAVE_FLAG | 仅保存canvas的matrix数组 | save()、saveLayer() |
CLIP_SAVE_FLAG | 仅保存canvas的当前大小 | save()、saveLayer() |
HAS_ALPHA_LAYER_SAVE_FLAG | 标识新建的bmp具有透明度,在与上层画布结合时,透明位置显示上图图像,与FULL_COLOR_LAYER_SAVE_FLAG冲突,若同时指定,则以HAS_ALPHA_LAYER_SAVE_FLAG为主 | saveLayer() |
FULL_COLOR_LAYER_SAVE_FLAG | 标识新建的bmp颜色完全独立,在与上层画布结合时,先清空上层画布再覆盖上去 | saveLayer() |
CLIP_TO_LAYER_SAVE_FLAG | 在保存图层前先把当前画布根据bounds裁剪,与CLIP_SAVE_FLAG冲突,若同时指定,则以CLIP_SAVE_FLAG为主 | saveLayer() |
public class MATRIX_SAVE_FLAG_View extends View { private Paint mPaint; public MATRIX_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.rotate(40); canvas.drawRect(100,0,200,100,mPaint); canvas.restore(); mPaint.setColor(Color.YELLOW); canvas.drawRect(100,0,200,100,mPaint); } }我们直接看OnDraw函数,先调用 canvas.save(Canvas.MATRIX_SAVE_FLAG)将canvas的位置矩阵保存起来,然后将画布旋转40度之后,画一个绿色矩形;
很明显,在canvas.restore()后,画布的旋转给恢复到了原来了状态。
然后我们再来看看,如果我们给画布裁剪,看还能不能被恢复
public class MATRIX_SAVE_FLAG_View extends View { private Paint mPaint; public MATRIX_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.clipRect(100,0,200,100); canvas.drawColor(Color.GREEN); canvas.restore(); canvas.drawColor(Color.YELLOW); } }效果图如下:
从效果图来看,我们恢复画布后,把画布全部染成了黄色,但并没有染全屏幕的画布,而只是clip后的一部分,这说明,被裁剪的画布没有被还原!
前面我们说了调用 canvas.save(Canvas.MATRIX_SAVE_FLAG)只会保存了位置矩阵!恢复时,也只会恢复画布的位置信息,有关画布的大小,是不会被恢复的!
public class MATRIX_SAVE_FLAG_View extends View { private Paint mPaint; public MATRIX_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.MATRIX_SAVE_FLAG|Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.rotate(40); canvas.drawRect(100,0,200,100,mPaint); canvas.restore(); mPaint.setColor(Color.YELLOW); canvas.drawRect(100,0,200,100,mPaint); } }效果图如下:
这里在保存Flag时,多了一个Canvas.HAS_ALPHA_LAYER_SAVE_FLAG,表示在新建的画布在合成到上一个画布上时,直接覆盖,不清空所在区域原图像,这个标识这里先忽略,我们后面会具体讲。
效果与原因都是与save()相同,指定保存Canvas.MATRIX_SAVE_FLAG,即canvas的位置信息,当调用canvas.revert()后,原始画布的旋转被恢复。所以再次画图到原始画布上时,是没有旋转的。
我们还是直接来看例子吧,裁剪:
下面我们举个例子来看看
public class MATRIX_SAVE_FLAG_View extends View { private Paint mPaint; public MATRIX_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.GREEN); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.MATRIX_SAVE_FLAG|Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.clipRect(100,0,200,100); canvas.restore(); canvas.drawColor(Color.YELLOW); } }效果图如下:
与上面的例子一样,在saveLayer中也只是保存Canvas.MATRIX_SAVE_FLAG,即canvas的位置信息,之后调用canvas.clipRect(100,0,200,100);将画板裁剪,注意我们在讲解canvas时提到了,无论哪个图层调用canvas的位置变换和裁剪操作,所有的画布都会受到连累,这些连累也只表现在画布以后的绘图上,之前画过的图像不会受到影响。
所以在clipRect之前画出来的全屏绿色是不受影响的,当restore()以后,canvas只恢复了原始画布的位置信息而原始画布的大小却无法被恢复,所以当再调用 canvas.drawColor(Color.YELLOW),也只能画出来一小块了
注意:在上面的例子中用到了canvas.clipRect(),这个函数是不支持硬件加速的,原因参见《自定义控件三部曲之绘图篇(十)——Paint之setXfermode(一)》,所以需要添加setLayerType函数来禁用硬件加速。
所以MATRIX_SAVE_FLAG标识的结论来了:
1、当save\saveLayer调用Canvas.MATRIX_SAVE_FLAG标识时只会保存画布的位置矩阵信息,在canvas.restore()时也只会恢复位置信息,而改变过的画布大小是不会被恢复的。
2、当使用canvas.saveLayer(Canvas.MATRIX_SAVE_FLAG)时,需要与Canvas.HAS_ALPHA_LAYER_SAVE_FLAG一起使用,不然新建画布所在区域原来的图像将被清空。(后面会讲原因)
public class CLIP_SAVE_FLAG_View extends View { private Paint mPaint; public CLIP_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.save(Canvas.CLIP_SAVE_FLAG); canvas.clipRect(100,0,200,100); canvas.restore(); canvas.drawColor(Color.YELLOW); } }效果图如下:
从效果图中可以看出在canvas.restore()后,canvas被恢复到初始化的全屏大小。
然后我们再看一个旋转的例子
public class CLIP_SAVE_FLAG_View extends View { private Paint mPaint; public CLIP_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.GREEN); canvas.drawRect(100,0,200,100,mPaint); canvas.save(Canvas.CLIP_SAVE_FLAG); canvas.rotate(40); canvas.restore(); mPaint.setColor(Color.YELLOW); canvas.drawRect(100,0,200,100,mPaint); } }效果图如下:
我们先画了一个绿色的矩形,之后旋转画布,然后在调用 canvas.restore()恢复画布之后,再画上一个同样的黄色矩形。
从效果图中可以看出,canvas在恢复时,并没有恢复旋转的画布,这也就是Canvas.CLIP_SAVE_FLAG的意义所在,只保存裁剪信息,不保存位置信息,所以恢复时,位置信息是不会被恢复的!
public class CLIP_SAVE_FLAG_View extends View { private Paint mPaint; public CLIP_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.CLIP_SAVE_FLAG|Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.clipRect(100,0,200,100); canvas.restore(); canvas.drawColor(Color.YELLOW); } }效果图如下:
效果与canvas.save一样,原因也很简单,因为Canvas.CLIP_SAVE_FLAG标识是可以恢复裁剪信息的。
然后再来看看旋转。
public class CLIP_SAVE_FLAG_View extends View { private Paint mPaint; public CLIP_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.GREEN); canvas.drawRect(100,0,200,100,mPaint); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.CLIP_SAVE_FLAG|Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.rotate(40); canvas.restore(); mPaint.setColor(Color.YELLOW); canvas.drawRect(100,0,200,100,mPaint); } }效果与canvas.save相同
因为Canvas.CLIP_SAVE_FLAG不能保存位置信息,所以在canvas.restore()后,旋转并没有被恢复。
所以CLIP_SAVE_FLAG标识的结论来了:
1、当save/saveLayer调用 Canvas.CLIP_SAVE_FLAG时只会保存画布的裁剪信息,在canvas.restore()时也只会恢复裁剪信息,而改变过的画布位置信息是不会被恢复的。
2、当使用canvas.saveLayer(Canvas.CLIP_SAVE_FLAG)时,需要与Canvas.HAS_ALPHA_LAYER_SAVE_FLAG一起使用,不然新建画布所在区域原来的图像将被清空。
public class ALPHA_COLOR_FALG_VIEW extends View { private Paint mPaint; public ALPHA_COLOR_FALG_VIEW(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0,0,500,500,mPaint,Canvas.FULL_COLOR_LAYER_SAVE_FLAG); canvas.drawRect(100,100,300,300,mPaint); canvas.restore(); } }效果图如下:
我们在saveLayer时,新建bitmap画布的大小为(0,0,500,500),然后在新建画布中画了一个矩形(100,100,300,300),由于我们使用的标识是Canvas.FULL_COLOR_LAYER_SAVE_FLAG,所以新建画布在与上一层画布合成时,会先把上一层画布对应区域的图像清空掉,然后再盖上新建画布。由于新建画布中除了绿色矩形,其它位置都是透明像素,所以就显示出Activity的底色(黑色)。如果你把activity的背景色在xml中设置为白色,做出来的效果图中,露出来的就是白色了:
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff" > …………对应的效果为:
public class ALPHA_COLOR_FALG_VIEW extends View { private Paint mPaint; public ALPHA_COLOR_FALG_VIEW(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0,0,500,500,mPaint,Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.drawRect(100,100,300,300,mPaint); canvas.restore(); } }效果图为:
从效果图中可以看出,saveLayer新建的画布在与上一层画布合成时,并没有把上一层画布对应区域清空,而是直接盖在上面。
public class ALPHA_COLOR_FALG_VIEW extends View { private Paint mPaint; public ALPHA_COLOR_FALG_VIEW(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0,0,500,500,mPaint,Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG); canvas.drawRect(100,100,300,300,mPaint); canvas.restore(); } }还是上面的例子,我们同时加入两个标识,看以哪个结果显示,效果图如下:
所以从效果图中也可以看出,当这两个标识同时使用时,以Canvas.HAS_ALPHA_LAYER_SAVE_FLAG为主;
public class ALPHA_COLOR_FALG_VIEW extends View { private Paint mPaint; public ALPHA_COLOR_FALG_VIEW(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0,0,500,500,mPaint,Canvas.MATRIX_SAVE_FLAG); canvas.rotate(40); canvas.drawRect(100, 100, 300, 300, mPaint); canvas.restore(); } }效果图如下:
从效果图中可以看出,在默认情况下使用的是Canvas.FULL_COLOR_LAYER_SAVE_FLAG标识,即先清空上一层画布对应区域的图像,然后再合成,所以这也是我们在上面的例子中强制添加HAS_ALPHA_LAYER_SAVE_FLAG标识的原因
所以有关这两个标识的结论来了:
1、HAS_ALPHA_LAYER_SAVE_FLAG表示新建的bitmap画布在与上一个画布合成时,不会将上一层画布内容清空,直接盖在上一个画布内容上面。
2、FULL_COLOR_LAYER_SAVE_FLAG则表示新建的bimap画布在与上一个画布合成时,先将上一层画布对应区域清空,然后再盖在上面。
3、当HAS_ALPHA_LAYER_SAVE_FLAG与FULL_COLOR_LAYER_SAVE_FLAG两个标识同时指定时,以HAS_ALPHA_LAYER_SAVE_FLAG为主
4、当即没有指定HAS_ALPHA_LAYER_SAVE_FLAG也没有指定FULL_COLOR_LAYER_SAVE_FLAG时,系统默认使用FULL_COLOR_LAYER_SAVE_FLAG;
public class CLIP_TO_LAYER_SAVE_FLAG_VIEW extends View { private Paint mPaint; public CLIP_TO_LAYER_SAVE_FLAG_VIEW(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0, 0, 500, 500, mPaint, Canvas.CLIP_TO_LAYER_SAVE_FLAG); canvas.restore(); canvas.drawColor(Color.YELLOW); } }效果图如下:
从效果图中可以看出,当我们调用canvas.saveLayer(0, 0, 500, 500, mPaint, Canvas.CLIP_TO_LAYER_SAVE_FLAG)时,canvas画板就被裁剪了,不仅影响了自己,而且还把view的原始画布给影响了,虽然在调用了canvas.restore(),但最后一句在将原始画布填充为黄色,也可以看出,原始画布没有被恢复!
public class CLIP_TO_LAYER_SAVE_FLAG_VIEW extends View { private Paint mPaint; public CLIP_TO_LAYER_SAVE_FLAG_VIEW(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0, 0, 500, 500, mPaint, Canvas.CLIP_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); canvas.restore(); canvas.drawColor(Color.YELLOW); } }效果图如下:
从效果图中可以看出canvas被恢复了,不过canvas被恢复也,也就失去了Canvas.CLIP_TO_LAYER_SAVE_FLAG标识的意义了。
所以这个CLIP_TO_LAYER_SAVE_FLAG标识的结论来了:
1、CLIP_TO_LAYER_SAVE_FLAG意义是在新建bitmap前,先把canvas给裁剪,一旦画板被裁剪,那么其中的各个画布都会被受到影响。而且由于它是在新建bitmap前做的裁剪,所以是无法恢复的;
2、当CLIP_TO_LAYER_SAVE_FLAG与CLIP_SAVE_FLAG标识共用时,在调用restore()后,画布将被恢复
public int save() public int save(int saveFlags) public int saveLayer(RectF bounds, Paint paint, int saveFlags) public int saveLayer(float left, float top, float right, float bottom,Paint paint, int saveFlags) public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) public int saveLayerAlpha(float left, float top, float right, float bottom,int alpha, int saveFlags)在save()、saveLayer()、saveLayerAlpha()保存画布后,都会返回一个ID值,这个ID值表示当前保存的画布信息的栈层索引(从0开始),比如保存在第三层,则返回2;
public void restoreToCount(int saveCount);它表示一直退栈,一直退到指定count的层数为栈顶为止;注意这个saveCount起始值是从1开始的,也就是说它比对应栈的索引要多1;
int id = canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.ALL_SAVE_FLAG); canvas.restoreToCount(id);调用canvas.saveLayer后,新保存的画布放在了第三层,返回的id的值是对应的索引即2
public class RestoreToCountView extends View { private Paint mPaint; private String TAG = "qijian"; public RestoreToCountView(Context context, AttributeSet attrs) { super(context, attrs); mPaint = new Paint(); mPaint.setColor(Color.RED); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int id1 = canvas.save(); canvas.clipRect(0,0,800,800); canvas.drawColor(Color.RED); Log.d(TAG,"count:"+canvas.getSaveCount()+" id1:"+id1); int id2 = canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.ALL_SAVE_FLAG); canvas.clipRect(100,100,700,700); canvas.drawColor(Color.GREEN); Log.d(TAG,"count:"+canvas.getSaveCount()+" id2:"+id2); int id3 = canvas.saveLayerAlpha(0,0,getWidth(),getHeight(),0xf0,Canvas.ALL_SAVE_FLAG); canvas.clipRect(200,200,600,600); canvas.drawColor(Color.YELLOW); Log.d(TAG,"count:"+canvas.getSaveCount()+" id3:"+id3); int id4 = canvas.save(Canvas.ALL_SAVE_FLAG); canvas.clipRect(300,300,500,500); canvas.drawColor(Color.BLUE); Log.d(TAG,"count:"+canvas.getSaveCount()+" id4:"+id4); } }在onDraw函数中,我们连续对canvas做裁剪,并且在裁剪后,把当前画布画上一层不同的颜色,然后把当前的栈的层数和最高层的索引打出来
Log日志如下:
然后我们更改一下上面的代码:
protected void onDraw(Canvas canvas) { super.onDraw(canvas); int id1 = canvas.save(); canvas.clipRect(0,0,800,800); canvas.drawColor(Color.RED); Log.d(TAG,"count:"+canvas.getSaveCount()+" id1:"+id1); int id2 = canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.ALL_SAVE_FLAG); canvas.clipRect(100,100,700,700); canvas.drawColor(Color.GREEN); Log.d(TAG,"count:"+canvas.getSaveCount()+" id2:"+id2); int id3 = canvas.saveLayerAlpha(0,0,getWidth(),getHeight(),0xf0,Canvas.ALL_SAVE_FLAG); canvas.clipRect(200,200,600,600); canvas.drawColor(Color.YELLOW); Log.d(TAG,"count:"+canvas.getSaveCount()+" id3:"+id3); int id4 = canvas.save(Canvas.ALL_SAVE_FLAG); canvas.clipRect(300,300,500,500); canvas.drawColor(Color.BLUE); Log.d(TAG,"count:"+canvas.getSaveCount()+" id4:"+id4); canvas.restoreToCount(id3); canvas.drawColor(Color.GRAY); Log.d(TAG,"count:"+canvas.getSaveCount()); }我们在最后添加上canvas.restoreToCount(id3);,然后把画布整个绘成灰色。
Log日志如下:
从代码中可以看出调用canvas.restoreToCount(id3)后,将恢复到生成id3之前的画布状态,id3之前的画布状态就是(100,100,700,700)
public class RestoreToCountView extends View { private Paint mPaint; private String TAG = "qijian"; public RestoreToCountView(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.RED); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(); Log.d(TAG,"count:"+canvas.getSaveCount()); canvas.save(Canvas.ALL_SAVE_FLAG); Log.d(TAG,"count:"+canvas.getSaveCount()); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.CLIP_SAVE_FLAG); Log.d(TAG,"count:"+canvas.getSaveCount()); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.MATRIX_SAVE_FLAG); Log.d(TAG,"count:"+canvas.getSaveCount()); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); Log.d(TAG,"count:"+canvas.getSaveCount()); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.ALL_SAVE_FLAG); Log.d(TAG,"count:"+canvas.getSaveCount()); } }在这个例子中,我们多次调用不同的save函数和不同的FLAG,然后将栈中层数打出来,日志如下:
从效果图中可以明显看出,每save一次,栈的层数都在加一,所以无论哪种save方法,哪个FLAG标识,保存画布时都使用的是同一个栈
所以restore()与restoreToCount(int count)的结论来了:
1、restore的意义是把回退栈中的最上层画布状态出栈,恢复画布状态。restoreToCount(int count)的意义是一直退栈,直到指定层count做为栈顶,将此之前的所有动作都恢复。
2、所以无论哪种save方法,哪个FLAG标识,保存画布时都使用的是同一个栈
3、restore()与restoreToCount(int count)针对的都是同一个栈,所以是完全可以通用和混用的。
好了,有关保存图层的知识到这里就结束了,这两篇内容理解起来可能会比较困难,多看两遍喽,有关FLAG标识的知识,如果看不懂就算了,会用ALL_SAVE_FLAG就行,其它标识用到的机会比较少。如果有机会开视频教程的话,再给大家具体演示一下,应该会比较好理解,暂且期待下吧。
如果本文有帮到你,记得加关注哦
源码下载地址:http://download.csdn.net/detail/harvic880925/9510189 (与第二篇对应资源合并在一个工程中)
请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/51332494 谢谢
如果你喜欢我的文章,那么你将会更喜欢我的微信公众号,将定期推送博主最新文章与收集干货分享给大家(一周一次)
自定义控件三部曲之绘图篇(十四)——Canvas与图层(二)
标签:
原文地址:http://blog.csdn.net/harvic880925/article/details/51332494