Android canvas.save()与canvas.restore()的使用总结
含义
canvas.save();
画布将当前的状态保存
canvas.restore();
画布取出原来所保存的状态
使用
canvas.save();与canvas.restore();一般结合使用,.save()函数在前,.restore()函数在后,用来保证在这两个函数之间所做的操作不会对原来在canvas上所画图形产生影响。比如下面这张图:
蓝色方块里面有三张图,两张正常画,一张倾斜45度角画
首先,你可以这样画:先画左上角和左下角的两个图,然后将画布倾斜45度角,再去画第三张图,这样是没问题的,代码如下:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//第一张
canvas.drawBitmap(bitmap, 0 , 0 , paint);
//第二张
canvas.drawBitmap(bitmap, 0 , getHeight()- bitmap.getHeight() , paint);
//旋转45
canvas.rotate(45 , getWidth()/2 , getHeight()/2);
//第三张
canvas.drawBitmap(bitmap, getWidth()/2- bitmap.getWidth()/2 , getHeight()/2- bitmap.getHeight()/2 , paint);
}
如果你要是按这样的顺序画:第一张–>倾斜45度的那一张–>第三张
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//第一张
canvas.drawBitmap(bitmap, 0 , 0 , paint);
//旋转45
canvas.rotate(45 , getWidth()/2 , getHeight()/2);
//第二张
canvas.drawBitmap(bitmap, getWidth()/2- bitmap.getWidth()/2 , getHeight()/2- bitmap.getHeight()/2 , paint);
//第三张
canvas.drawBitmap(bitmap, 0 , getHeight()- bitmap.getHeight() , paint);
}
那么结果就变成了这样:
wtf!第三张图为什么出去了,而且它也没有老实的呆在左下角!
我们来看上面的代码:
第一行:画第一张左上角的图
第二行:旋转画布45度
第三行:画第二张倾斜的图
第四行:画第三张左下角的图
看起来是没有什么问题,但是第二行代码将canvas旋转了45度,所以以后再往canvas上画图的时候都是在这个旋转45度的基础上进行的,也就是说整个坐标系旋转了45度,它已经不再是原来水平竖直的坐标系了,所以第三次画的图会出现偏移。那么如何解决?如下:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//第一张
canvas.drawBitmap(bitmap, 0 , 0 , paint);
//保存画布状态
canvas.save();
//旋转45
canvas.rotate(45 , getWidth()/2 , getHeight()/2);
//第二张
canvas.drawBitmap(bitmap, getWidth()/2- bitmap.getWidth()/2 , getHeight()/2- bitmap.getHeight()/2 , paint);
//取出原来保存的状态
canvas.restore();
//第三张
canvas.drawBitmap(bitmap, 0 , getHeight()- bitmap.getHeight() , paint);
}
在你画完第一张图以后,当要开始画倾斜的那一张的时候,因为你要对画布进行角度的旋转,并且你只想让当前的这一张产生倾斜的角度,所以应该在将画布进行旋转之前将原来的状态进行保存,在画完倾斜的图片后将原来的状态取出来再进行后续的操作,那么你刚才旋转画布的操作就不会对你后续产生影响。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
2016-12-02 Android解决Fragment多层嵌套时onActivityResult无法正确回调的问题
2016-12-02 Fragment嵌套Fragment时遇到的那些坑
2016-12-02 Android 多个Fragment嵌套导致的三大BUG