SurfaceView 的概念和用途java
surfaceview是view的一個子類,能夠直接從內存或者DMA等硬件接口中取得圖像數據,是一個很是重要的繪圖視圖。他的特性是:能夠在主線程以外的線程中向屏幕繪圖,這樣能夠避免畫圖任務繁重的時候形成的主線程阻塞,從而提升了程序的反應速度。在遊戲開發過程當中多用到SurfaceView,遊戲中的背景、人物、動畫等等在畫布canvas中畫出。android
Surfaceview的實現和方法canvas
1.實現步驟ide
a.繼承SurfaceView函數
b.實現SurfaceHolder.Callback 接口
動畫
2.須要重寫的方法this
//在surface的大小發生改變時激發 public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){} //在建立時觸發,通常在這裏調用畫圖的線程 public void surfaceCreated(SurfaceHolder holder){} //在銷燬時激發,通常在這裏將畫圖的線程中止、釋放。 public void surfaceDestroyed(SurfaceHolder holder) {}
在整個過程當中:繼承SurfaceView並實現SurfaceHolder.Callback接口---->SurfaceView.getHolder()得到SerfaceHolder對象 ----->而後SurfaceHolder.addCallback(callback) 添加回調函數 ----->SurfaceHolder.lockCanvas() 得到Canvas對象並鎖定畫布 ---->canvas繪畫 -----》 surfaceHolder。unlockCanvasAndPost(Canvas canvas)結束鎖定畫圖,並提交改變,將圖形顯示。spa
3.SurfaceHolder方法線程
SurfaceHolder,surface的控制器,用來操縱surface。處理它的Canvas上畫的效果和動畫,控制表面,大小,像素等。code
要注意的幾個方法:
(1)、abstract void addCallback(SurfaceHolder.Callback callback); // 給SurfaceView當前的持有者一個回調對象。 (2)、abstract Canvas lockCanvas(); // 鎖定畫布,通常在鎖定後就能夠經過其返回的畫布對象Canvas,在其上面畫圖等操做了。 (3)、abstract Canvas lockCanvas(Rect dirty); // 鎖定畫布的某個區域進行畫圖等..由於畫完圖後,會調用下面的unlockCanvasAndPost來改變顯示內容。 // 相對部份內存要求比較高的遊戲來講,能夠不用重畫dirty外的其它區域的像素,能夠提升速度。 (4)、abstract void unlockCanvasAndPost(Canvas canvas); // 結束鎖定畫圖,並提交改變。
3、經過自定義的SurfaceView組件實現的一個繪圖類
package com.example.mydrawingboard; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PaintFlagsDrawFilter; import android.graphics.Path; import android.graphics.Paint.Style; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnTouchListener; public class MyView extends SurfaceView implements SurfaceHolder.Callback,OnTouchListener { Paint paint=new Paint(); //建立一個畫筆 Path path=new Path(); //建立一個保存路徑 //因爲咱們這是自定義控件,因此要使用有兩個參數的構造函數 public MyView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub getHolder().addCallback(this); //添加一個回調函數 paint.setTextSize(15); paint.setColor(Color.GREEN); paint.setStyle(Style.STROKE); //定義爲空心 setOnTouchListener(this); } //建立一個繪圖方法 public void draw(){ //建立一個畫布而且鎖定畫布 Canvas canvas=getHolder().lockCanvas(); canvas.drawColor(Color.WHITE); canvas.drawPath(path, paint); //畫布抗鋸齒 canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG)); //在整個繪圖結束以後調用解鎖畫圖 getHolder().unlockCanvasAndPost(canvas); } public void clear(){ path.reset(); draw(); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder arg0) { //在surface開始的時候就開始執行draw draw(); } @Override public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub } @Override public boolean onTouch(View arg0, MotionEvent arg1) { // TODO Auto-generated method stub switch (arg1.getAction()) { case MotionEvent.ACTION_DOWN: path.moveTo(arg1.getX(),arg1.getY()); draw(); break; case MotionEvent.ACTION_MOVE: path.lineTo(arg1.getX(),arg1.getY()); draw(); break; } //若是返回false,則只能執行down操做; return true; } }