Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 畫圖類View與SurfaceView之學習

Android 畫圖類View與SurfaceView之學習

編輯:關於Android編程

在開發游戲開發中,android相應的提供了幾個重要的模塊: 1、顯示界面的視圖:  Android 提供 View 和 SurfaceView  2、控制游戲整體結構: android 提供 Activity  3、邏輯控制類:專門用於處理游戲的邏輯計算 4、處理游戲界面與用戶交互事件 : 利用 View 類提供的 onKeyDown onKeyUp onTounchEvent等方法   我們這裡簡單熟悉一下如何在視圖上畫東西。   1、View 類: android.view.View  View 是Android中的一個超類,這個類幾乎包含了所有的屏幕類型。每一個View都有一個用於繪畫的畫布,這個畫布 可以進行任何擴展。 任何一個View類都只需要重寫onDraw方法來實現界面顯示,任何一個View都只需要重寫 OnDraw 方法來實現界面顯示,自定義的視圖可以是復雜的3D實現,也可以是非常簡單的文本或位圖。   Android 中有個重要的東東: Android UI 線程  在這裡 http://blog.csdn.net/andyhuabing/article/details/11921887 有對其簡要精典的介紹及注意點,這裡就不再重復說明了。   這裡來個簡單例子說明一下View的用法,利用線程變更顯示顏色,通過上下左右移動矩形   TestView.java 類如下: [java]  package com.example.testondraw;      import android.content.Context;   import android.graphics.Canvas;   import android.graphics.Color;   import android.graphics.Paint;   import android.view.View;      /**   * View 是Android中的一個超類,這個類幾乎包含了所有的屏幕類型。每一個View都有一個用於繪畫的畫布,這個畫布 可以進行任何擴展。   *    * 任何一個View類都只需要重寫onDraw方法來實現界面顯示。   *    */   public class TestView extends View {       int miCount = 0;       int x = 10, y = 10;          public TestView(Context context) {           super(context);       }          @Override       protected void onDraw(Canvas canvas) {           if (miCount < 100)           {               miCount++;           }           else            {               miCount = 0;           }           //繪圖           Paint mPaint = new Paint();              switch (miCount%4)           {           case 0:               mPaint.setColor(Color.BLUE);                   break;           case 1:               mPaint.setColor(Color.GREEN);                  break;           case 2:               mPaint.setColor(Color.RED);               break;           case 3:               mPaint.setColor(Color.YELLOW);               break;           default:               mPaint.setColor(Color.WHITE);               break;           }           // 繪制矩形           canvas.drawRect(x, y, x + 120, y + 80, mPaint);       }   }     如何在 Acitivty 使用呢?示例代碼如下: [java]   package com.example.testondraw;      import java.util.List;      import android.app.Activity;   import android.app.ActivityManager;   import android.content.Context;   import android.graphics.Bitmap;   import android.os.Bundle;   import android.os.Handler;   import android.os.Message;   import android.util.DisplayMetrics;   import android.util.Log;   import android.view.KeyEvent;   import android.view.Menu;      public class MainActivity extends Activity {       static final String TAG = "MainActivity";       private TestView mTestView = null;       private TestSurfaceView mTestSurfaceView = null;       private int mWidth = 0, mHeight = 0;       private MyHandler mHandler = new MyHandler();          @Override       public void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);              initView();              startTestView();                      // setContentView(R.layout.main);       }          void initView() {           // 使用自定義的View           mTestView = new TestView(this);           setContentView(mTestView);                  DisplayMetrics dm = new DisplayMetrics();           getWindowManager().getDefaultDisplay().getMetrics(dm);           mWidth = dm.widthPixels;           mHeight = dm.heightPixels;           Log.i(TAG, "Display Metrics width:" + mWidth + " mHeight:" + mHeight);       }          @Override       public boolean onCreateOptionsMenu(Menu menu) {           getMenuInflater().inflate(R.menu.main, menu);           return true;       }          void startTestView() {           Thread th = new Thread(new Runnable() {                  @Override               public void run() {                   while (!Thread.currentThread().isInterrupted()) {                       // 使用postInvalidate可以直接在線程中更新界面   //                  mTestView.postInvalidate();                                              // 使用發消息給UI線程                       Message msg = Message.obtain();                       msg.what = 1;                       mHandler.sendMessage(msg);                          try {                           Thread.sleep(100);                       } catch (InterruptedException e) {                           Thread.currentThread().interrupt();                       }                   }               }           });           th.start();       }          class MyHandler extends Handler {           @Override           public void handleMessage(Message msg) {               switch (msg.what) {               case 1:                   mTestView.invalidate();                   break;               default:                   break;               }               super.handleMessage(msg);           }       }          public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {           switch (keyCode) {           case KeyEvent.KEYCODE_DPAD_DOWN:               if (mTestView.y >= mHeight)                   mTestView.y = 0;               mTestView.y += 10;               break;           case KeyEvent.KEYCODE_DPAD_UP:               if (mTestView.y <= 0)                   mTestView.y = mHeight;               mTestView.y -= 10;               break;           case KeyEvent.KEYCODE_DPAD_LEFT:               if (mTestView.x <= 0)                   mTestView.x = mWidth;               mTestView.x -= 10;               break;           case KeyEvent.KEYCODE_DPAD_RIGHT:               if (mTestView.x >= mWidth)                   mTestView.x = 0;               mTestView.x += 10;               break;           }           return false;       };   }     2、SurfaceView  android.view.SurfaceView 當執行效率有要求很高時,View類就無法滿足需求。必須使用 SurfaceView 類 -- 利用雙緩沖技術   使用SurfaceView提供給需要直接畫像素而不是使用畫窗體部件的應用使用。 而每個Surface創建一個Canvas對象,用來管理View在Surface上的繪畫操作。   簡要說明一下具體的方法及使用: SurfaceHolder 對象需要通過 getHolder() 獲取 在 Layout 上擺一個 SurfaceView 組件: mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView1); SurfaceHolder holder = mSurfaceView.getHolder();   對於SurfaceView 的創建,銷毀及變更 @SuppressWarnings("unused") private SurfaceHolder.Callback mSurfaceCbk = new SurfaceHolder.Callback() {   @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    // 在Surface 大小發生變更時觸發 // TODO Auto-generated method stub   }     @Override public void surfaceCreated(SurfaceHolder holder) { // 在創建 Surface 時觸發 // TODO Auto-generated method stub   }   @Override public void surfaceDestroyed(SurfaceHolder holder) { // 在銷毀 Surface 時觸發 // TODO Auto-generated method stub   } };   添加及刪除 SurfaceView 的回調函數: display.addCallback(mSurfaceCbk); display.removeCallback(mSurfaceCbk);   Canvas 的使用: lockCanvas  鎖定畫布,繪圖之前必須鎖定畫布才能得到當前畫布對象 unlockCanvasAndPost 開始繪制時鎖定畫布,繪制完成之後解鎖畫布   下面例子是繪制一個不斷變換顏色的圓,並實現 SurfaceView 的事件處理 TestSurfaceView.java 代碼: [java]  package com.example.testondraw;      import android.content.Context;   import android.graphics.Bitmap;   import android.graphics.Canvas;   import android.graphics.Color;   import android.graphics.Paint;   import android.view.SurfaceHolder;   import android.view.SurfaceView;      /**   * 使用SurfaceView提供給需要直接畫像素而不是使用畫窗體部件的應用使用。   * 而每個Surface創建一個Canvas對象,用來管理View在Surface上的繪畫操作。   */   public class TestSurfaceView extends SurfaceView implements           SurfaceHolder.Callback {       // 控制循環       private boolean mbLoop = false;          // 定義SurfaceHolder對象       private SurfaceHolder mSurfaceHolder = null;       private int miCount = 0;       public int x = 50, y = 50;       private int mWidth = 1280,mHeight = 720;       private Bitmap mBitmap = null;              public TestSurfaceView(Context context) {           super(context);              // 實例化SurfaceHolder           mSurfaceHolder = this.getHolder();              // 添加回調           mSurfaceHolder.addCallback(this);           this.setFocusable(true);       }          public void setDisplayWH(int w, int h) {           mWidth = w;           mHeight = h;       }          public void setBitmap(Bitmap bitmap) {           this.mBitmap = bitmap;       }          @Override       public void surfaceChanged(SurfaceHolder holder, int format, int width,               int height) {           // TODO Auto-generated method stub                  }          @Override       public void surfaceCreated(SurfaceHolder holder) {           mbLoop = true;              Thread th = new Thread(new Runnable() {                  @Override               public void run() {                   while (mbLoop){                       try {                           Thread.sleep(200);                       } catch (InterruptedException e) {                           e.printStackTrace();                       }                          synchronized( mSurfaceHolder ){                           drawBitmap();                           DrawData();                       }                   }               }           });           th.start();       }          @Override       public void surfaceDestroyed(SurfaceHolder holder) {           mbLoop = false;       }          private void drawBitmap() {           // 鎖定畫布,得到canvas           if (mSurfaceHolder == null || this.mBitmap == null)               return;              Canvas canvas = mSurfaceHolder.lockCanvas();           if (canvas == null) {               return;           }              // 繪圖           Paint paint = new Paint();           paint.setAntiAlias(true);           paint.setColor(Color.BLUE);              canvas.drawBitmap(this.mBitmap, 0, 0, paint);              // 繪制後解鎖,繪制後必須解鎖才能顯示           mSurfaceHolder.unlockCanvasAndPost(canvas);       }          // 繪圖方法       private void DrawData() {           if (mSurfaceHolder == null)               return;              // 鎖定畫布,得到canvas           Canvas canvas = mSurfaceHolder.lockCanvas();           if (canvas == null) {               return;           }              if (miCount < 100) {               miCount++;           } else {               miCount = 0;           }              // 繪圖           Paint mPaint = new Paint();           mPaint.setAntiAlias(true);           mPaint.setColor(Color.BLACK);              // 繪制矩形--清屏作用           canvas.drawRect(0, 0, mWidth, mHeight, mPaint);                      switch (miCount % 4) {           case 0:               mPaint.setColor(Color.BLUE);               break;           case 1:               mPaint.setColor(Color.GREEN);               break;           case 2:               mPaint.setColor(Color.RED);               break;           case 3:               mPaint.setColor(Color.YELLOW);               break;           default:               mPaint.setColor(Color.WHITE);               break;           }              // 繪制矩形--           canvas.drawCircle(x, y, 50, mPaint);                      // 繪制後解鎖,繪制後必須解鎖才能顯示           mSurfaceHolder.unlockCanvasAndPost(canvas);       }   }     測試使用例子:   [java]   package com.example.testondraw;      import java.util.List;      import android.app.Activity;   import android.app.ActivityManager;   import android.content.Context;   import android.graphics.Bitmap;   import android.os.Bundle;   import android.os.Handler;   import android.os.Message;   import android.util.DisplayMetrics;   import android.util.Log;   import android.view.KeyEvent;   import android.view.Menu;   import android.view.SurfaceHolder;   import android.view.SurfaceView;      public class MainActivity extends Activity {       static final String TAG = "MainActivity";       private TestSurfaceView mTestSurfaceView = null;       private int mWidth = 0, mHeight = 0;          @Override       public void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);              initView();              startTestSurfaceView();                      // setContentView(R.layout.main);       }          void initView() {           // 使用自定義的View           mTestSurfaceView = new TestSurfaceView(this);           setContentView(mTestSurfaceView);                     DisplayMetrics dm = new DisplayMetrics();           getWindowManager().getDefaultDisplay().getMetrics(dm);           mWidth = dm.widthPixels;           mHeight = dm.heightPixels;           Log.i(TAG, "Display Metrics width:" + mWidth + " mHeight:" + mHeight);       }          @Override       public boolean onCreateOptionsMenu(Menu menu) {           getMenuInflater().inflate(R.menu.main, menu);           return true;       }          public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {           switch (keyCode) {           case KeyEvent.KEYCODE_DPAD_DOWN:               if (mTestSurfaceView.y >= mHeight)                   mTestSurfaceView.y = 0;               mTestSurfaceView.y += 10;               break;           case KeyEvent.KEYCODE_DPAD_UP:               if (mTestSurfaceView.y <= 0)                   mTestSurfaceView.y = mHeight;               mTestSurfaceView.y -= 10;               break;           case KeyEvent.KEYCODE_DPAD_LEFT:               if (mTestSurfaceView.x <= 0)                   mTestSurfaceView.x = mWidth;               mTestSurfaceView.x -= 10;               break;           case KeyEvent.KEYCODE_DPAD_RIGHT:               if (mTestSurfaceView.x >= mWidth)                   mTestSurfaceView.x = 0;               mTestSurfaceView.x += 10;               break;           case KeyEvent.KEYCODE_BACK:               this.finish();               break;           }           return false;       };          void startTestSurfaceView() {           mTestSurfaceView.setDisplayWH(mWidth, mHeight);           }   }    
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved