android Canvas 的save 和 restore

本文详细解释了在Android开发中如何使用Canvas的save和restore方法来控制画布状态,确保旋转、平移等操作仅影响特定区域的绘图,而不会影响后续的绘制任务。通过示例代码演示了如何在旋转红色方块时保持蓝色方块不受影响,以及在代码片段中如何正确使用save和restore方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

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

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

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

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

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

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

 

在读Android SDK里面的samples里面游戏的时候,很多时候都看到对canvas的save()和restore()运用。

  下面是个小程序,使用了这两个方面,使得旋转红色方块的时候,保证蓝色方块不受影响。

  代码如下:

 

package com.ray.test;
  import android.app.Activity;
  import android.content.Context;
  import android.graphics.Canvas;
  import android.graphics.Color;
  import android.graphics.Paint;
  import android.os.Bundle;
  import android.view.SurfaceHolder;
  import android.view.SurfaceView;
  public class Test extends Activity {

  /** Called when the activity is first created. */

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new MyView(this));

  }

  class MyView extends SurfaceView implements SurfaceHolder.Callback{
  private SurfaceHolder mHolder;
  private Canvas canvas;
  public MyView(Context context) {
  super(context);
    mHolder = getHolder();
  mHolder.addCallback(this);
  }

  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width,
  int height) {
  }

  @Override
  public void surfaceCreated(SurfaceHolder holder) {
  canvas = mHolder.lockCanvas();
  Paint mPaint = new Paint();
  mPaint.setColor(Color.BLUE);
  canvas.drawRect(100, 200, 200, 300, mPaint);
  canvas.save();
  canvas.rotate(45);
  mPaint.setColor(Color.RED);
  canvas.drawRect(150, 10, 200, 60, mPaint);
  canvas.restore();
   mHolder.unlockCanvasAndPost(canvas);
  }

  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {
  // TODO Auto-generated method stub
  }
  }
  }


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

再一次理解:canvas可能会做旋转,平移,切割等动作,然后为了让这些动作只在特定的一个程序段产生作用,不会影响下面你需要继续画的物体,可以通过 save和restore来做,相当于你本来走在一条大路上,忽然你觉得想尿尿,但是又怕回来找不到刚才走到的位置,所以你标记保存起来,然后你离去到一个幽静而又僻远的小茅房做动作,做完之后,你restore一下发现自己又回到了原来在大路上的位置,这样你可以继续走了。(很恶,但是很形象)

看看我下面的代码,如果有save 和 restore,那么平移、缩放、旋转等操作只对 save到 restore之间的代码有影响。也就是说只有红色的方块是旋转的。
如图:


 
            canvas = mHolder.lockCanvas();  
            Paint mPaint = new Paint();  
            mPaint.setColor(Color.BLUE);  
            canvas.drawRect(100, 200, 200, 300, mPaint);  
              
            canvas.save();  //注释1
            canvas.rotate(45);  
            mPaint.setColor(Color.RED);  
            canvas.drawRect(150, 10, 200, 60, mPaint);  
           canvas.restore(); //注释2 
            
            
            mPaint.setColor(Color.GREEN);  
            canvas.drawRect(200, 10, 250, 100, mPaint);  
            mHolder.unlockCanvasAndPost(canvas);  

            canvas = mHolder.lockCanvas();  
            Paint mPaint = new Paint();  
            mPaint.setColor(Color.BLUE);  
            canvas.drawRect(100, 200, 200, 300, mPaint);  
              
            canvas.save();  //注释1
            canvas.rotate(45);  
            mPaint.setColor(Color.RED);  
            canvas.drawRect(150, 10, 200, 60, mPaint);  
           canvas.restore(); //注释2 
            
            
            mPaint.setColor(Color.GREEN);  
            canvas.drawRect(200, 10, 250, 100, mPaint);  
            mHolder.unlockCanvasAndPost(canvas);  



如果上面的代码,注释1和注释2部分的代码被注释的话,那么绿色的方块一样是被旋转的。
如图:

http://rayleung.javaeye.com/blog/440623

http://cnmsdn.com/html/201006/1276969135ID6245.html

http://blog.youkuaiyun.com/surmountyourself/archive/2010/07/27/5768368.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值