1、Surface
Surface在SDK的文檔中的描述是這樣的:Handle onto a raw buffer that is being managed by the screen compositor,Android中的Surface就是一個用來畫圖形(graphics)或圖像(image)的地方,對於View及其子類,都是畫在Surface上,各Surface對象經過Surfaceflinger合成到frameBuffer,每一個Surface都是雙緩衝,它有一個backBuffer和一個frontBuffer,Surface中建立了Canvas對象,用來管理Surface繪圖操做,Canvas對應Bitmap,存儲Surface中的內容。流程爲:java
1:建立一個Bitmap對象。android
2:建立一個Canvas對象關聯建立的Bitmap對象。canvas
3:在Canvas上進行繪製。app
4:鎖定Canvas畫布。ide
5:將Bitmap內容繪製到backBuffer中去。函數
6:解鎖Canvas畫布。this
2、SurfaceView
SurfaceView是視圖類View的子類,且實現了Parcelable接口且實現了Parcelable接口,其中內嵌了一個專門用於繪製的Surface,SurfaceView能夠控制這個Surface的格式和尺寸,以及Surface的繪製位置。能夠理解爲Surface就是管理數據的地方,SurfaceView就是展現數據的地方。spa
3、SurfaceHolder
SurfaceHolder是一個接口,相似於一個surace的監聽器。經過下面三個回調方法監聽Surface的建立、銷燬或者改變。.net
SurfaceView中調用getHolder方法,能夠得到當前SurfaceView中的surface對應的SurfaceHolder,SurfaceHolder中重要的方法有:線程
1: abstract void addCallback(SurfaceHolder.Callback callback );爲SurfaceHolder添加一個SurfaceHolder.Callback回調接口。
2: abstract Canvas lockCanvas() ;獲取Surface中的Canvas對象,並鎖定之。所獲得的Canvas對象。
3:abstract void unlockCanvasAndPost(Canvas canvas);當修改Surface中的數據完成後,釋放同步鎖,並提交改變,而後將新的數據進行展現。
4、SurfaceHolder.Callback
SurfaceHolder.Callback是SurfaceHolder接口內部的靜態子接口,SurfaceHolder.Callback中定義了三個接口方法:
1:public void sufaceChanged(SurfaceHolder holder,int format,int width,int height){}//Surface的大小發生改變時調用。
2: public void surfaceCreated(SurfaceHolder holder){}//Surface建立時激發,通常在這裏調用畫面的線程。
3: public void surfaceDestroyed(SurfaceHolder holder){}//銷燬時激發,通常在這裏將畫面的線程中止、釋放。
SurfaceView和View最本質的區別在於:SurfaceView是在一個新起的單獨線程中能夠從新繪製畫面而View必須在UI的主線程中更新畫面。下面是SurfaceView的例子:
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Paint.Style;
- import android.graphics.drawable.BitmapDrawable;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
- import android.view.KeyEvent;
- import android.view.MotionEvent;
- import android.view.SurfaceHolder.Callback;
-
- public class MySurfaceView extends SurfaceView implements Runnable, Callback {
- private SurfaceHolder mHolder; // 用於控制SurfaceView
- private Thread t; // 聲明一條線程
- private volatile boolean flag; // 線程運行的標識,用於控制線程
- private Canvas mCanvas; // 聲明一張畫布
- private Paint p; // 聲明一支畫筆
- float m_circle_r = 10;
-
- public MySurfaceView(Context context) {
- super(context);
-
- mHolder = getHolder(); // 得到SurfaceHolder對象
- mHolder.addCallback(this); // 爲SurfaceView添加狀態監聽
- p = new Paint(); // 建立一個畫筆對象
- p.setColor(Color.WHITE); // 設置畫筆的顏色爲白色
- setFocusable(true); // 設置焦點
- }
-
- /**
- * 當SurfaceView建立的時候,調用此函數
- */
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- t = new Thread(this); // 建立一個線程對象
- flag = true; // 把線程運行的標識設置成true
- t.start(); // 啓動線程
- }
-
- /**
- * 當SurfaceView的視圖發生改變的時候,調用此函數
- */
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- }
-
- /**
- * 當SurfaceView銷燬的時候,調用此函數
- */
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- flag = false; // 把線程運行的標識設置成false
- mHolder.removeCallback(this);
- }
-
- /**
- * 當屏幕被觸摸時調用
- */
- @Override
- public boolean onTouchEvent(MotionEvent event) {
-
- return true;
- }
-
- /**
- * 當用戶按鍵時調用
- */
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
- }
- return super.onKeyDown(keyCode, event);
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- surfaceDestroyed(mHolder);
- return super.onKeyDown(keyCode, event);
- }
-
- @Override
- public void run() {
- while (flag) {
- try {
- synchronized (mHolder) {
- Thread.sleep(100); // 讓線程休息100毫秒
- Draw(); // 調用自定義畫畫方法
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- if (mCanvas != null) {
- // mHolder.unlockCanvasAndPost(mCanvas);//結束鎖定畫圖,並提交改變。
-
- }
- }
- }
- }
-
- /**
- * 自定義一個方法,在畫布上畫一個圓
- */
- protected void Draw() {
- mCanvas = mHolder.lockCanvas(); // 得到畫布對象,開始對畫布畫畫
- if (mCanvas != null) {
- Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
- paint.setColor(Color.BLUE);
- paint.setStrokeWidth(10);
- paint.setStyle(Style.FILL);
- if (m_circle_r >= (getWidth() / 10)) {
- m_circle_r = 0;
- } else {
- m_circle_r++;
- }
- Bitmap pic = ((BitmapDrawable) getResources().getDrawable(
- R.drawable.qq)).getBitmap();
- mCanvas.drawBitmap(pic, 0, 0, paint);
- for (int i = 0; i < 5; i++)
- for (int j = 0; j < 8; j++)
- mCanvas.drawCircle(
- (getWidth() / 5) * i + (getWidth() / 10),
- (getHeight() / 8) * j + (getHeight() / 16),
- m_circle_r, paint);
- mHolder.unlockCanvasAndPost(mCanvas); // 完成畫畫,把畫布顯示在屏幕上
- }
- }
- }