Android 利用SurfaceView進行圖形繪制


SurfaceView使用介紹

  SurfaceView是View的一個特殊子類,它的目的是另外提供一個線程進行繪制操作。

 

  要使用SurfaceView進行繪制,步驟如下:

  1.用SurfaceView進行繪制,首先要創建一個類,繼承 SurfaceView,同時這個類應該實現SurfaceHolder.Callback接口。

  這個接口中的三個回調函數(surfaceChanged(SurfaceHolder holder, int format, int width, int height),surfaceCreated(SurfaceHolder holder),surfaceDestroyed(SurfaceHolder holder))分別對應Surface何時更改、創建和銷毀。

  2.對Surface對象的操作是通過SurfaceHolder來進行的。所以,在你的SurfaceView類初始化的時候,你需要調用 getHolder()來獲得SurfaceHolder對象,然后用addCallback()加上回調接口(因為你的類實現了相應的接口,所以此處傳入this即可)。

  3.在你的SurfaceView類中應該建立一個線程類,處理繪制操作。為此,要向這個線程類傳遞上面獲得的SurfaceHolder對象。

  4.繪制:在線程類的run()方法中進行繪制操作,通過lockCanvas()方法獲得Canvas對象,然后就可以用這個對象進行繪制,繪制完成后調用unlockCanvasAndPost(),傳入Canvas對象,這時Surface將會按Canvas進行繪制。

  注意:每次利用SurfaceHolder獲得畫布時,前一次的內容將會保留。

 

代碼示例

復制代碼
package com.example.hellosurfaceview;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MySurfaceView extends SurfaceView implements
        SurfaceHolder.Callback
{

    private DrawThread mThread = null;

    public MySurfaceView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        init();
    }

    public MySurfaceView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        init();
    }

    public MySurfaceView(Context context)
    {
        super(context);
        init();
    }

    private void init()
    {
        Log.d(AppConstants.LOG_TAG, "init");

        SurfaceHolder holder = getHolder();
        holder.addCallback(this);

        mThread = new DrawThread(holder);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        Log.d(AppConstants.LOG_TAG, "onSizeChanged");
        super.onSizeChanged(w, h, oldw, oldh);

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder)
    {
        Log.d(AppConstants.LOG_TAG, "surfaceCreated");
        mThread.setRun(true);
        mThread.start();

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height)
    {
        Log.d(AppConstants.LOG_TAG, "surfaceChanged");
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        Log.d(AppConstants.LOG_TAG, "surfaceDestroyed");
        mThread.setRun(false);

    }

    /**
     * 繪制線程類
     * 
     */
    public class DrawThread extends Thread
    {
        private SurfaceHolder mHolder = null;
        private boolean isRun = false;

        public DrawThread(SurfaceHolder holder)
        {
            Log.d(AppConstants.LOG_TAG, "DrawThread Constructor");
            mHolder = holder;

        }

        public void setRun(boolean isRun)
        {
            Log.d(AppConstants.LOG_TAG, "DrawThread setRun: " + isRun);
            this.isRun = isRun;
        }

        @Override
        public void run()
        {
            Log.d(AppConstants.LOG_TAG, "DrawThread run");
            int count = 0;

            while (isRun)
            {
                Canvas canvas = null;
                synchronized (mHolder)
                {
                    try
                    {
                        Log.d(AppConstants.LOG_TAG, "Drawing-------------");
                        canvas = mHolder.lockCanvas();
                        canvas.drawColor(Color.WHITE);
                        Paint p = new Paint();
                        p.setColor(Color.BLACK);

                        Rect r = new Rect(100, 50, 300, 250);
                        canvas.drawRect(r, p);
                        canvas.drawText("這是第" + (count++) + "秒", 100, 310, p);

                        Thread.sleep(1000);// 睡眠時間為1秒

                    }
                    catch (Exception e)
                    {
                        Log.d(AppConstants.LOG_TAG, "throw Exception in run");
                        e.printStackTrace();

                    }
                    finally
                    {
                        if (null != canvas)
                        {
                            mHolder.unlockCanvasAndPost(canvas);
                        }
                    }

                }

            }
        }

    }

}
復制代碼

 

 

參考資料

  官方文檔:

  API Guides:Canvas and Drawables

  http://developer.android.com/guide/topics/graphics/2d-graphics.html

  SurfaceView:

  http://developer.android.com/reference/android/view/SurfaceView.html

  SurfaceHolder:

  http://developer.android.com/reference/android/view/SurfaceHolder.html

  博客:

  Android之SurfaceView學習(一):

  http://www.cnblogs.com/xuling/archive/2011/06/06/android.html

  剖析 SurfaceView:

  http://blog.csdn.net/xiaominghimi/article/details/6090575

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM