android中的surfaceview执行的效率比较高,它可以直接访问一个画布,应用程序通过它直接绘制像素。android图形界面中有一个比较重要的概念是surface,何谓surface?简单的讲,surface相当于画板,所有的图像(view及其子类)都是要花在surface上的。每个surface会创建一个Canvas对象(其属性是会时常变的)--一个用来管理view在surface上绘图的操作。换句通俗的话讲,surface是画板,Canvas相当与话的动作,Paint相当于画笔。因而Canvas中包含了很多画的动作,比如话矩形,画圆等等。
回到主题,SurfaceView和一般的View有什么区别呢?SurfaceView不需要通过线程来更新视图,但绘制之前通常必须使用SurfaceHolder(通过getHolder()方法获取,是控制画布大小和改变的对象)的lockCanvas方法锁定(当SurfaceHolder的type设置为SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS除外),然后用unclockCanvasAndPost释放画布。
SurfaceHolder可以通过removeCallback来移除监听。
回到主题,SurfaceView和一般的View有什么区别呢?SurfaceView不需要通过线程来更新视图,但绘制之前通常必须使用SurfaceHolder(通过getHolder()方法获取,是控制画布大小和改变的对象)的lockCanvas方法锁定(当SurfaceHolder的type设置为SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS除外),然后用unclockCanvasAndPost释放画布。
SurfaceView和普通的View一样,有相同的事件处理原则,这里不再过多的讨论。
SurfaceView画布的变化和前面讲的一样,是通过SurfaceHoder来控制的,SurfaceHolder的addCallback方法注册一个SurfaceView变化的跟踪器,应用程序需要实现SurfaceHoder.Callback接口,这个接口有三个方法,分别是:
surfaceCreated: 在Surface被创建的时候触发。
surfaceChanged:在Surface的大小改变的时候触发。
surfaceDistoryed:在Surface被销毁的时候触发。
SurfaceView画布的变化和前面讲的一样,是通过SurfaceHoder来控制的,SurfaceHolder的addCallback方法注册一个SurfaceView变化的跟踪器,应用程序需要实现SurfaceHoder.Callback接口,这个接口有三个方法,分别是:
surfaceCreated: 在Surface被创建的时候触发。
surfaceChanged:在Surface的大小改变的时候触发。
surfaceDistoryed:在Surface被销毁的时候触发。
SurfaceHolder可以通过removeCallback来移除监听。
代码示例:
package com.caravelsoft.surfaceview; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceView; public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback { private boolean mLoop = false; private SurfaceHolder mHolder = null; private int m_y = 50; private int mCount = 0; public MySurfaceView(Context context) { super(context); initView(); // TODO Auto-generated constructor stub } public MySurfaceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub initView(); } public MySurfaceView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub initView(); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub mLoop = true; new Thread(mRunner).start(); } public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub mLoop = false; } private void initView() { mHolder = this.getHolder(); mHolder.addCallback(this); this.setFocusable(true); } private Runnable mRunner = new Runnable() { public void run() { // TODO Auto-generated method stub while (mLoop) { try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (mHolder) { onDrawView(); } } } }; private void onDrawView() { if (mHolder == null) return; // 获取画布 Canvas canvas = mHolder.lockCanvas(); if (null == canvas) return; if (mCount < 100) { mCount++; } else { mCount = 0; } // 绘图,定义画笔 Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.BLACK); // 绘制矩形 canvas.drawRect(0, 0, 320, 480, paint); switch (mCount % 4) { case 0: paint.setColor(Color.BLUE); break; case 1: paint.setColor(Color.GREEN); break; case 2: paint.setColor(Color.LTGRAY); break; case 3: paint.setColor(Color.RED); break; } canvas.drawCircle((320 - 25) / 2, m_y, 50, paint); // 释放canvas mHolder.unlockCanvasAndPost(canvas); } }