含义
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);
    }

在你画完第一张图以后,当要开始画倾斜的那一张的时候,因为你要对画布进行角度的旋转,并且你只想让当前的这一张产生倾斜的角度,所以应该在将画布进行旋转之前将原来的状态进行保存,在画完倾斜的图片后将原来的状态取出来再进行后续的操作,那么你刚才旋转画布的操作就不会对你后续产生影响。

Android canvas.save()与canvas.restore()的使用总结的更多相关文章

  1. Android中canvas.save()和canvas.restore()的使用

    自己定义控件时经常遇到重写View的Ondraw()方法,Ondraw()方法经常设计到save()和restore()这两个方法.这两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的. ...

  2. canvas save()和canvas restore()状态的保存和恢复使用方法及实例

    canvas.save()用来保存先前状态的 canvas.restore()用来恢复之前保存的状态 注:两种方法必须搭配使用,否则没有效果 <!DOCTYPE html> <htm ...

  3. 【转】Android Canvas的save(),saveLayer()和restore()浅谈

    Android Canvas的save(),saveLayer()和restore()浅谈 时间:2014-12-04 19:35:22      阅读:1445      评论:0      收藏: ...

  4. Android Canvas的save(),saveLayer()和restore()浅谈

    save()  saveLayer()  restore() 1.在自定义控件当中你onMeasure和onLayout的工作做完成以后就该绘制该控件了,有时候需要自己在控件上添加一些修饰来满足需求 ...

  5. Android Canvas save和restoreToCount

    @Override public void draw(Canvas canvas) { if (mDrawable!=null) { int sc=canvas.save(); if (mAnimat ...

  6. Canvas中的save方法和restore方法

    初学者也许会误认为canvas中save方法是用来保存绘图状态的图形,而restore方法是用来还原之前保存的绘图状态的图形,其实不然. save():保存当前的绘图状态. restore():恢复之 ...

  7. Android核心分析之二十八Android GDI之Surface&Canvas

    Surface&Canvas Canvas为在画布的意思.Android上层的作图几乎都通过Canvas实例来完成,其实Canvas更多是一种接口的包装.drawPaints ,drawPoi ...

  8. 初识canvas,使用canvas做一个百分比加载进度的动画

    canvas作为H5中重要的新增特性,使开发者可以用它来创作各种令人惊叹的作品.先来看一下浏览器对canvas的支持情况. <canvas> 标签定义图形,比如图表和其他图像,我们使用脚本 ...

  9. 【canvas系列】canvas实现“ 简单的Amaziograph效果”--画对称图

    标题很难引人入胜,先放个效果图好了 如果图片吸引不了你,那我觉得也就没啥看的了. demo链接: https://win7killer.github.io/can_demo/demo/draw_rol ...

随机推荐

  1. Go安装配置和《菜鸟教程之Go语言教程》学习笔记

    Go 语言是一种让代码分享更容易的编程语言 菜鸟教程-Go语言教程(这个教程过于基础,体现不了Go的特性和强大.) 下载/安装Go语言 https://golang.org/dl/ Mac OS X ...

  2. Fragment: 使用newInstance()来实例化fragment(转)

    先说结论: 1. 当需要给Fragment传值时,使用newInstance()方式来实例化一个Fragment,能够更好的将该Fragment使用的参数捆绑起来,不必每次实例化时都写下面的代码: B ...

  3. kotlin基础 尾递归

    尾调用的重要性在于它可以不在调用栈上面添加一个新的堆栈帧——而是更新它,如同迭代一般. 尾递归因而具有两个特征: 调用自身函数(Self-called): 计算仅占用常量栈空间(Stack Space ...

  4. 关于在windows平台下将应用制作成windows服务及服务依赖的感想

    在某些情况下,应用需要部署在windows平台下,单纯的手动点击exe执行文件或java -jar xxx.jar在实际生产环境中不是最佳实践(制作成bat启动文件置于启动项里,服务器启动后,需要人工 ...

  5. 将.cer证书导入java密钥库?

    导入.cer从浏览器下载的证书文件(打开网址并挖掘详细信息)到cacerts keystore中java_home\jre\lib\security为我工作,而不是尝试生成和使用我自己的密钥库. 去你 ...

  6. 发布微信小程序体验版

    小程序这么火,一直没有做过.因为公司有个业务需要做小程序就顺带学习了一把. 1)本次是采用<微信开发者工具 Stable v1.02.1904090>进行的开发: 2)前端使用的是微信官方 ...

  7. 将你的数据导入到json格式

    不知道为什么大家那么偏爱json格式,清晰?跨平台?或许这都是它的优点吧,之前我都是将我的数据放到txt中,今后就用json吧.初步写了一个写入json的模板,就这么用吧. def get_qq_05 ...

  8. Python的编码规范

    7. 什么是 PEP8? 8号Python增强提案,是针对Python代码格式而编写的风格指南 8. 了解 Python 之禅么? 通过 import this 语句可以获取其具体的内容.它告诉大家何 ...

  9. 如何利用Docker构建基于DevOps的全自动CI

    来自用户的DevOps实践分享,分享从开发代码到生产环境部署的一条龙操作的实践及经验, 包含工具技术的选型及考量.私有代码库与私有镜像库的应用等. (一)容器服务的Rancher选型 1.为什么说是下 ...

  10. JVM方法栈的工作过程,方法栈和本地方法栈有什么区别。

    JVM的本地方法栈   对于一个运行中的Java程序而言,它还可能会用到一些跟本地方法相关的数据区.当某个线程调用一个本地方法时,它就进入了一个全新的并且不再受虚拟机限制的世界.本地方法可以通过本地方 ...