首页 > 代码库 > SurfaceView绘图机制

SurfaceView绘图机制

虽然前面都使用的View来进行绘图,但View绘图机制存在两个缺陷:

1、缺乏双缓冲机制

2、更新图像时,必须更新View上的整张图片,效率低。

所以在游戏绘制中推荐使用SurfaceView。它可以只对指定区域进行更新,可以提高效率。下面用一个简单示例来演示SurfaceView的使用:

Activity:

package com.home.activity;   import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.os.Bundle; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import android.view.View; import android.view.View.OnTouchListener;   import com.home.surfaceviewtest.R;   public class SurfaceViewActivity extends Activity {     // SurfaceHolder负责维护SurfaceView上绘制的内容      private SurfaceHolder holder;     private Paint paint;       @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.main);         paint = new Paint();         // 获取SurfaceView实例          SurfaceView surface = (SurfaceView) findViewById(R.id.main_sv);         // 初始化SurfaceHolder对象          holder = surface.getHolder();         holder.addCallback(new Callback() {             //当surface将要被销毁时回调该方法              @Override             public void surfaceDestroyed(SurfaceHolder holder) {               }             //当surface被创建时回调该方法              @Override             public void surfaceCreated(SurfaceHolder holder) {                 // 锁定整个SurfaceView                  Canvas canvas = holder.lockCanvas();                 // 获取背景资源                  Bitmap bitmap = BitmapFactory.decodeResource(                         SurfaceViewActivity.this.getResources(),                         R.drawable.image2);                 // 绘制背景                  canvas.drawBitmap(bitmap, 0, 0, null);                 // 绘制完成,释放画布,提交修改                  holder.unlockCanvasAndPost(canvas);                 // 重新锁两次,避免下次lockCanvas遮挡                  holder.lockCanvas(new Rect(0, 0, 0, 0));                 holder.unlockCanvasAndPost(canvas);                 holder.lockCanvas(new Rect(0, 0, 0, 0));                 holder.unlockCanvasAndPost(canvas);             }             //当一个surface的格式或大小发生改变时回调该方法              @Override             public void surfaceChanged(SurfaceHolder holder, int format,                     int width, int height) {               }         });         surface.setOnTouchListener(new OnTouchListener() {               @Override             public boolean onTouch(View v, MotionEvent event) {                 // 只处理按下事件                  if (event.getAction() == MotionEvent.ACTION_DOWN) {                     int cx = (int) event.getX();                     int cy = (int) event.getY();                     // 锁定SurfaceView的局部区域,只更新局部内容                      Canvas canvas = holder.lockCanvas(new Rect(cx - 60,                             cy - 60, cx + 60, cy + 60));                     // 保存canvas的当前状态                      canvas.save();                     // 旋转画布                      canvas.rotate(30, cx, cy);                     paint.setColor(Color.RED);                     // 绘制红色方块                      canvas.drawRect(cx - 40, cy - 40, cx, cy, paint);                     // 恢复canvas之前的保存状态                      canvas.restore();                     paint.setColor(Color.GREEN);                     // 绘制绿色方块                      canvas.drawRect(cx, cy, cx + 40, cy + 40, paint);                     // 绘制完成,释放画布,提交修改                      holder.unlockCanvasAndPost(canvas);                 }                 return false;             }         });     }   }  package com.home.activity; import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.os.Bundle;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;import android.view.View;import android.view.View.OnTouchListener; import com.home.surfaceviewtest.R; public class SurfaceViewActivity extends Activity { // SurfaceHolder负责维护SurfaceView上绘制的内容 private SurfaceHolder holder; private Paint paint;  @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.main);  paint = new Paint();  // 获取SurfaceView实例  SurfaceView surface = (SurfaceView) findViewById(R.id.main_sv);  // 初始化SurfaceHolder对象  holder = surface.getHolder();  holder.addCallback(new Callback() {   //当surface将要被销毁时回调该方法   @Override   public void surfaceDestroyed(SurfaceHolder holder) {    }   //当surface被创建时回调该方法   @Override   public void surfaceCreated(SurfaceHolder holder) {    // 锁定整个SurfaceView    Canvas canvas = holder.lockCanvas();    // 获取背景资源    Bitmap bitmap = BitmapFactory.decodeResource(      SurfaceViewActivity.this.getResources(),      R.drawable.image2);    // 绘制背景    canvas.drawBitmap(bitmap, 0, 0, null);    // 绘制完成,释放画布,提交修改    holder.unlockCanvasAndPost(canvas);    // 重新锁两次,避免下次lockCanvas遮挡    holder.lockCanvas(new Rect(0, 0, 0, 0));    holder.unlockCanvasAndPost(canvas);    holder.lockCanvas(new Rect(0, 0, 0, 0));    holder.unlockCanvasAndPost(canvas);   }   //当一个surface的格式或大小发生改变时回调该方法   @Override   public void surfaceChanged(SurfaceHolder holder, int format,     int width, int height) {    }  });  surface.setOnTouchListener(new OnTouchListener() {    @Override   public boolean onTouch(View v, MotionEvent event) {    // 只处理按下事件    if (event.getAction() == MotionEvent.ACTION_DOWN) {     int cx = (int) event.getX();     int cy = (int) event.getY();     // 锁定SurfaceView的局部区域,只更新局部内容     Canvas canvas = holder.lockCanvas(new Rect(cx - 60,       cy - 60, cx + 60, cy + 60));     // 保存canvas的当前状态     canvas.save();     // 旋转画布     canvas.rotate(30, cx, cy);     paint.setColor(Color.RED);     // 绘制红色方块     canvas.drawRect(cx - 40, cy - 40, cx, cy, paint);     // 恢复canvas之前的保存状态     canvas.restore();     paint.setColor(Color.GREEN);     // 绘制绿色方块     canvas.drawRect(cx, cy, cx + 40, cy + 40, paint);     // 绘制完成,释放画布,提交修改     holder.unlockCanvasAndPost(canvas);    }    return false;   }  }); } }

布局XML:

LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical">       <SurfaceView        android:id="@+id/main_sv"        android:layout_width="match_parent"        android:layout_height="match_parent"/>   </LinearLayout>  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">     <SurfaceView        android:id="@+id/main_sv"        android:layout_width="match_parent"        android:layout_height="match_parent"/> </LinearLayout>

 

SurfaceView绘图机制