当前位置:首页 > 编程笔记 > 正文
已解决

android高级开发自定义View-canvas的save和restore方法的使用-大厂高频面试题

来自网友在路上 152852提问 提问时间:2023-09-27 19:41:35阅读次数: 52

最佳答案 问答题库528位专家为你答疑解惑

背景:

hi,粉丝朋友们:
大家好!上星期举办的framework模拟面试活动,许多粉丝也在积极探讨面试过程中的一些问题。比如今天要讲解的问题:
一般很多做应用同学简历都会写一个"熟练自定义view",这个技能基本上android高级应用开发都很多同学会写。面试官针对这个技能的面试比较容易考察的问题就是:
你是否知道canvas里面有一个save和restore方法,针对这个canvas的save和restore方法你可以说说对他的理解吗?

哈哈哈有没有很熟悉这个面试问题,先说一下为啥要考查这个问题呢?
其实很多高级ui,其实大部分时候都需要比较复杂的绘制,大部分时候都需要灵活掌握绘制相关方法,canvas属于最为频繁的一种,而且复杂ui经常需要涉及到旋转,平移,等操作,这时候就需要save和restore的出场。

Canvas的save和restore介绍

/*** Saves the current matrix and clip onto a private stack.* <p>* 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()*/
public int save() {return nSave(mNativeCanvasWrapper, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
}

可以看到这里注释已经比较清楚,保存当前canvas的矩阵matrix和裁剪clip数据到一个stack中

再来看看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.*/public void restore() {if (!nRestore(mNativeCanvasWrapper)&& (!sCompatibilityRestore || !isHardwareAccelerated())) {throw new IllegalStateException("Underflow in restore - more restores than saves");}}

这里的restore和save一般是对应的,前面save是保存canvas的matrix,clip到stack,这里restore就是从stack把顶部的matrix和clip取出应用。
如下图所示:
在这里插入图片描述
这里的save1,save2,save3其实本质可以认为是某一个时刻的matrix和clip的数据。restore时候就是获取这个save数据,然后应用到canvas上,当然肯定应用前canvas会被reset。

总结大白话理解:
canvas经常可能因为绘制需求,需要对canvas进行旋转平移等绘制,但是旋转平移后整个坐标系就变化了,下一部分还要绘制时候,可能想基于原始坐标来,但是已经被平移了旋转了,怎么回到原来呢?
难道还要挨个旋转回去和平移回去么?当然不是哈,这样做的话大家都感觉太傻了,所以就有了今天讲解的save和restore出现。在canvas平移旋转前save,然后想回到原来既可以调restore

代码具体应用理解:

    protected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint paint = new Paint();//第一个基于原点坐标绘制的离左边距离10paint.setColor(Color.RED);canvas.drawRect(10,10,70,30,paint);//canvas已经平移了100canvas.translate(100,100);paint.setColor(Color.YELLOW);//这时候绘制的坐标是0,但是因为平移了,所以间隔原点其实是100canvas.drawRect(0,10,60,30,paint);paint.setColor(Color.BLACK);//这时候绘制的坐标是200,但是因为平移了,所以间隔原点其实是200+100canvas.drawRect(200,10,320,30,paint);}

在这里插入图片描述

但是第三个黑块如果不想跟随第二个黄绘制时候的平移影响怎么办??代码如下:

    protected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint paint = new Paint();//第一个基于原点坐标绘制的离左边距离10paint.setColor(Color.RED);canvas.drawRect(10,10,70,30,paint);//平移前对canvas进行savecanvas.save();//canvas已经平移了100canvas.translate(100,100);paint.setColor(Color.YELLOW);//这时候绘制的坐标是0,但是因为平移了,所以间隔原点其实是100canvas.drawRect(0,10,60,30,paint);//第二个绘制完成后进行restorecanvas.restore();paint.setColor(Color.BLACK);//这时候绘制的坐标是200,那么就是200canvas.drawRect(200,10,320,30,paint);}

执行结果如下:
在这里插入图片描述

黑色重新回到原始坐标系,没有受到第二个平移的影响。

更多精彩内容手把手视频或关注下面公众号“千里马学框架”:
https://www.bilibili.com/video/BV1TK4y1c7Ku/

查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"android高级开发自定义View-canvas的save和restore方法的使用-大厂高频面试题":http://eshow365.cn/6-14832-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!