在创建新的控件或修改现有的控件时,我们都会涉及到重写控件或View的onDraw方法。

onDraw方法会传入一个Canvas对象,它是你用来绘制控件视觉界面的画布。

在onDraw方法里,我们经常会看到调用save和restore方法,它们到底是干什么用的呢?

❑ save:用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。

❑ restore:用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。

save和restore要配对使用(restore可以比save少,但不能多),如果restore调用次数比save多,会引发Error。

例如:我们先想在画布上绘制一个右向的三角箭头,当然,我们可以直接绘制,另外,我们也可以先把画布旋转90°,画一个向上的箭头,然后再旋转回来(这种旋转操作对于画圆周上的标记非常有用)。然后,我们想在右下角有个20像素的圆,那么,onDraw中的核心代码是:

int px = getMeasuredWidth();

int py = getMeasuredWidth();

// Draw background

canvas.drawRect(0, 0, px, py, backgroundPaint);

canvas.save();

canvas.rotate(90, px/2, py/2);

// Draw up arrow

canvas.drawLine(px / 2, 0, 0, py / 2, linePaint);

canvas.drawLine(px / 2, 0, px, py / 2, linePaint);

canvas.drawLine(px / 2, 0, px / 2, py, linePaint);

canvas.restore();

// Draw circle

canvas.drawCircle(px - 10, py - 10, 10, linePaint);

效果如图1所示:

图1

如果我们不调用save和restore会是什么样子呢?如图2所示:

图2

从这两个图中,我们就能看到圆圈位置的明显差异。不进行Canvas的save和restore操作的话,所有的图像都是在画布旋转90°后的画布上绘制的。当执行完onDraw方法,系统自动将画布恢复回来。save和restore操作执行的时机不同,就能造成绘制的图形不同。

所以,save和restore之间,往往夹杂的是对Canvas的特殊操作。

canvas 中save和restore的用法的更多相关文章

  1. canvas中save()和restore()方法

    save()和restore()方法是绘制复杂图形不可缺少的方法它们是分别用来保存和恢复canvas状态的,都没有参数 save():用来保存Canvas的状态.save之后,可以调用Canvas的平 ...

  2. HTML5中canvas的save和restore方法

    canvas的save和restore方法: save() 方法把当前绘画状态的一份拷贝压入到一个保存图像状态的栈中.这里的绘画状态指坐标原点.变形时的变化矩阵(该矩阵是调用 rotate().sca ...

  3. canvas的save与restore方法的作用

    网上搜罗了一堆资料,最后总结一下. save:用来保存Canvas的状态.save之后,可以调用Canvas的平移.放缩.旋转.错切.裁剪等操作. restore:用来恢复Canvas之前保存的状态. ...

  4. android_浅析canvas的save()和restore()方法

    <span style="font-size:18px;"> </span> <span style="font-size:18px;&qu ...

  5. Canvas的save和restore

    在onDraw方法里,我们经常会看到调用save和restore方法,它们到底是干什么用的呢? int px = getMeasuredWidth(); int py = getMeasuredWid ...

  6. canvas绘制时钟及注释及save和restore的用法

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

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

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

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

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

  9. [js高手之路] html5 canvas系列教程 - 状态详解(save与restore)

    本文内容与路径([js高手之路] html5 canvas系列教程 - 开始路径beginPath与关闭路径closePath详解)是canvas中比较重要的概念.掌握理解他们是做出复杂canvas动 ...

随机推荐

  1. jQuery $.fn 方法扩展~

    //以下代码紧跟在引进的jquery.js代码后面 <script type="Text/JavaScript"> $(function (){ //扩展myName方 ...

  2. 9月27日Bootstrap

    Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷.Bootstrap ...

  3. logo上传

  4. JavaWeb学习笔记——JSP标准标签库JSTL

  5. notification的使用

    示例: NotificationManager nm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); No ...

  6. cookie和浏览器

    XHR API允许应用添加自定义的HTTP首部(通过setRequestHeader()方法),同时也有一些首部都是应用代码不能设定的. Accept-Charset.Accept-Encoding. ...

  7. (转载)iOS UILabel自定义行间距时获取高度

    本文介绍一下自定义行间距的UILabel的高度如何获取,需要借助一下开源的UILabel控件:TTTAttributedLabel 附下载地址 https://github.com/TTTAttrib ...

  8. Web启动服务器上的某一个服务

    情景是这样的.. 网页打开一个数据列表..数据要求实时从其他多个平台上获取.. 所以就有了一个Web页面..还有个WinService的服务来定时获取这些数据... 问题来了.. 发现Service有 ...

  9. jquery 中的事件冒泡

    废话少说,先来一段代码热热身: <!DOCTYPE html> <html> <head> <title>demo</title> < ...

  10. MYSQL的锁介绍,以及死锁发生情况-带例子

    mysql锁能在并发情况下的mysql进行更好的优化 MySQL有三种锁的级别:页级.表级.行级,这3种锁的特性可大致归纳如下: 表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生锁冲突的概率最高 ...