2012-03-17

使用 SurfaceView 介面來處理貼圖

如果不使用 Android 現成的 Widget (ImageView 與 ImageButton) 來處理圖片的話, 我覺得要在 Android 中貼圖並不是很方便, 從引用圖片來源開始, 一直到圖片的呈現, 整個過程十分冗長; 況且處理圖形的指令總是一長串 ... 但是, 現成的 Widget 也不一定能符合設計者的需要, 當應用程式需要較高的顯示效率與較獨特的操作介面時 (如遊戲軟體), 那麼那些方便的 Widget 就不太適合了 !

這篇的重點就在於使用 SurfaceView 介面來進行貼圖的動作, SurfaceView 介面最適合開發顯示速率較快的應用程式, 不過, 使用這個介面來處理圖片並不輕鬆 ! 就像我前面說過的那樣, 而且整個過程一開始並不容易理解, 一時之間也不容易解釋清楚, 那 ~ 有沒有淺顯易懂的方式 ? 我的答案是 -- 沒有 ! 建議你, 只有透過不斷的練習, 才能熟練它 ! 進一步理解它 !

我使用 SurfaceView 介面貼了一張圖, 如下 :

只貼一張圖, 座標 x : 50 , y : 100

程式碼如下 : (紅色字體為重點)
大部份的註解我順便寫在程式碼內了

// 主程式
public class surfaceviewTest extends Activity {
    /** Called when the activity is first created. */
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
        DrawTest drawTest = new DrawTest(this);
        setContentView(drawTest);
    }
}

==========================================

// 另一個類別 surfaceviewTest
public class DrawTest extends SurfaceView implements SurfaceHolder.Callback {
   
    //呼叫getHolder()方法來取得 SurfaceHolder,並指給 holder
    SurfaceHolder holder = getHolder();
    Bitmap bp;
    Canvas canvas;
    int x=50,y=100;  //貼圖在螢幕上的 x,y 座標

    // DrawTest 建構子
    public DrawTest(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
       
        //把這個 class 本身(extends SurfaceView)
        //透過 holder 的 Callback()方法連結起來
        //下面這行也可寫成 getHolder().addCallback(this);
        holder.addCallback(this);
       
        //設定圖片來源(此處使用預設的圖片)
        bp = BitmapFactory.decodeResource(getResources(),
                                                  R.drawable.icon);
    }

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

        //在 canvas 畫布上貼圖的三個步驟

        //1. 鎖住畫布
        canvas = holder.lockCanvas();
        //2. 在畫布上貼圖
        canvas.drawBitmap(bp,x,y,null);
        //3. 解鎖並po出畫布
        holder.unlockCanvasAndPost(canvas);
    }
   
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // TODO Auto-generated method stub
    }

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

與 SurfaceHolder.Callback 相關聯的三個程序 :
public void surfaceCreated(...) -- surface 建立時
public void surfaceChanged(...) -- surface 改變時
public void surfaceDestroyed(...) -- surface 結束時

上述貼圖的主要步驟是寫在 surfaceCreated 程序中
一張靜態的圖是看不出 SurfaceView 的能力的, 如果要讓圖 "動"起來, 則還需要配合執行緒的運用, 透過執行緒不斷去改變圖片的座標並反覆貼上圖片, 就可以達到動態的效果囉 ! 想朝 Android App 遊戲相關的應用軟體發展, 練習在 SurfaceView 中貼圖只是一個開端, 先從這個基礎出發, 再配合物件導向的程式架構及執行緒的應用, 才能建構出一個完整的應用程式 .^_^.

您可以延伸閱讀本部落格使用 SurfaceView 類別的其他範例 :

動態物件的產生與捕捉
模擬物件的生命週期
模擬拖曳小圖示的 Android 程式

沒有留言:

張貼留言

搜尋此網誌