SurfaceVie

      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釋放畫布。

      SurfaceView和普通的View一樣,有相同的事件處理原則,這裏不再過多的討論。
      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);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章