Android canvas.save()和canvas.restore()的理解

来源:互联网 发布:重庆市软件行业协会 编辑:程序博客网 时间:2024/05/19 04:03

原文地址 http://blog.csdn.net/leoleohan/article/details/50827236

Canvas相当于一块画布,该类中常用的方法如下:

  • drawRect(RectF rect, Paint paint)
  • drawPath(Path path, Paint paint)
  • drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
  • drawLine(float startX, float startY, float stopX, float stopY, 
    Paintpaint)
  • drawPoint(float x, float y, Paint paint)
  • drawText(String text, float x, floaty, Paint paint)
  • drawCircle(float cx, float cy, float radius,Paint paint)
  • drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

canvas.save()和canvas.restore()有什么用呢? 
- canvas.save( ):用来保存Canvas的状态 
- canvas.restore( ):用来恢复Canvas旋转、缩放等之后的状态,当和canvas.save( )一起使用时,恢复到canvas.save( )保存时的状态。

下面写一个简单的demo验证一下这个结论。

1、获取View的宽高尺寸

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> x = getMeasuredWidth();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> y = getMeasuredWidth();</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

2、画最外面的圆

<code class="hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//画最外面的圆</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.drawCircle(x / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, y / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, x / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, paint);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

这里写图片描述 
3、画类似表盘效果的刻度

<code class="hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//画刻度</span>paint.setColor(Color.BLUE);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.drawLine(x / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, y / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>, x / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, paint);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.save();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//注意,这里调用了保存canvas的方法</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>; i++) {    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">rotate</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">30</span>, x / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, y / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>);    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.drawLine(x / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, y / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>, x / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, paint);}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

这里写图片描述 
此时,画布已经顺时针旋转了3个30度,即90度。并且,在旋转画布之前已经调用了canvas.save()方法,所以此时保存的canvas的状态是未旋转时的正常状态。

4、继续画一条直线,观察效果

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">//给画笔加粗,换成黄色paint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setStrokeWidth</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>paint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setColor</span>(Color<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.YELLOW</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>//画一条黄色粗线,便于区分canvas<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.drawLine</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">x</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">y</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">x</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">y</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>, paint)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

这里写图片描述 
观察运行效果图,最新绘制的黄线已经被旋转了90度。为什么呢?因为画布已经在之前旋转了90度了。

下面在绘制黄线的代码之前,调用canvas.restore()恢复画布的状态

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">canvas<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.restore</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;//恢复画布状态</span>paint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setStrokeWidth</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>paint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setColor</span>(Color<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.YELLOW</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>canvas<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.drawLine</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">x</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">y</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">x</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">y</span> / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>, paint)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

此时运行效果如图: 
这里写图片描述 
黄线又恢复了正常显示。 
当然,不使用canvas.restore(),而是继续旋转-90度画布,也是可以恢复画布到初始状态的。

<code class="hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">canvas</span>.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">rotate</span>(-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">90</span>, x / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, y / <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

感兴趣的读者可以把canvas.save()的调用放在旋转画布90度代码的后面,再次运行程序观察有什么变化。

0 0
原创粉丝点击