Android中View與SurfaceView的區別要點打賞

首先介紹一下View類,View類是android的一個超類,每一個View都有一個用于繪畫的畫布,這個畫布可以進行任意的擴展。有的時候我們需要自定義VIew實現自己想要的視圖。view、SurfaceView是游戲開發中經常用到的視圖。

View:顯示視圖,內置畫布,提供圖形繪制函數、觸屏事件、按鍵事件函數等;必須在UI主線程內更新畫面,速度較慢。

SurfaceView:基于view視圖進行拓展的視圖類,更適合2D游戲的開發;是view的子類,類似使用雙緩機制,在新的線程中更新畫面所以刷新界面速度比view快。

下面介紹一下View和SurfaceView區別:

View:必須在UI的主線程中更新畫面,用于被動更新畫面。

surfaceView:UI線程和子線程中都可以。在一個新啟動的線程中重新繪制畫面,主動更新畫面。

先實現一個VIew的例子,新建一個MyView類基礎View:

public class MyView extends View {

	int count=0;     
	public int r=10; //圓的半徑
	public MyView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		if(count< =100){
			count++;	
		}else{
			count=0;
		}
		//繪圖
		Paint paint=new Paint();
		switch (count % 4) {
		case 0:
			paint.setColor(Color.BLUE);
			break;
		case 1:
			paint.setColor(Color.YELLOW);
			break;
		case 2:
			paint.setColor(Color.GRAY);
			break;
		case 3:
			paint.setColor(Color.RED);
			break;
		default:
			paint.setColor(Color.WHITE);
			break;
		}
		canvas.drawCircle((320+r)/2, (480+r)/2, r, paint);
	}

}

下面是需要顯示它的TestViewActivity類:

public class TestViewActivity extends Activity {

	private MyView myView;
	private int REFRESH;
	private Handler handler=new Handler(){
		public void handleMessage(android.os.Message msg) {
			if(msg.what==REFRESH){
				myView.invalidate();
			}
		};
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		myView=new MyView(this);
		setContentView(myView);

		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				while(true){
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				handler.sendEmptyMessage(REFRESH);
				//使用postInvalidate可以直接在線程中更新UI界面
				//myView.postInvalidate();
			  }	
			}
		}).start();
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		myView.r+=2;
		return super.onTouchEvent(event);

	}
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if(keyCode==KeyEvent.KEYCODE_BACK){
			finish();
		}
		return super.onKeyDown(keyCode, event);
	}
}

注釋的部分是可以在線程中更新UI界面,當然也可以在handler中調用invalidate方法更新界面,這樣就可以通過線程不斷的重畫改變小球的顏色,而且點擊畫面后小球會慢慢變大。
這是其中的一張截圖:
surfaceview
下面看一下用SurfaceView是怎么實現的,照例創建一個MySurfaceView類:

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable {

	SurfaceHolder surfaceHolder;
	int count=0;
	int r=10;
	public MySurfaceView(Context context) {
		super(context);
		 //實例化SurfaceHolder對象
		surfaceHolder=this.getHolder();
		//為SurfaceHolder添加一個回調函數
		surfaceHolder.addCallback(this);
		this.setFocusable(true);
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){  //死循環 來不停地畫
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		synchronized (surfaceHolder) {
			Draw();
		}
	   }
	}
	//繪圖方法
	public void Draw(){
		//鎖定畫布  得到Canvas
		Canvas canvas=surfaceHolder.lockCanvas();
		if(surfaceHolder==null || canvas==null){
			return ;
		}
		if(count< =100){
			count++;
		}else{
			count=0;
		}
		Paint paint=new Paint();
		switch (count % 4) {
		case 0:
			paint.setColor(Color.BLUE);
			break;
		case 1:
			paint.setColor(Color.YELLOW);
			break;
		case 2:
			paint.setColor(Color.GRAY);
			break;
		case 3:
			paint.setColor(Color.RED);
			break;
		default:
			paint.setColor(Color.WHITE);
			break;
		}
		canvas.drawCircle((320+r)/2, (480+r)/2, r, paint);
		//解鎖畫布
		surfaceHolder.unlockCanvasAndPost(canvas);
	}
    //在surface大小改變時激發
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub

	}
    //在surface創建時激發
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		//開啟視圖線程
	    new Thread(this).start();
	}
	 //在surface銷毀時激發
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub

	}

}

SurfaceView不需要通過線程來更新視圖,但在繪圖之前必須使用lockCanvas方法鎖定畫布,并得到畫布,然后在畫布上繪制;當繪制完成后,使用unlockCanvasAndPost方法來解鎖畫布,這樣才能顯示在屏幕上。

public class TestSurfaceViewActivity extends Activity {
	MySurfaceView  mySurfaceView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		 mySurfaceView=new MySurfaceView(this);
		setContentView(mySurfaceView);
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		mySurfaceView.r+=2;
		return super.onTouchEvent(event);
	}
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if(keyCode==KeyEvent.KEYCODE_BACK){
			finish();
		}
		return super.onKeyDown(keyCode, event);
	}
}

運行效果和上面的一樣,只是實現方式不同。
原文來自CSDN:wangkuifeng0118的專欄

Android中View與SurfaceView的區別要點
文章《Android中View與SurfaceView的區別要點》二維碼
  • 微信打賞
  • 支付寶打賞

已有9條評論

  1. 若雁

    謝謝您阿,我非常高興

    2016-01-04 19:03 回復
  2. 軟件分享

    技術流!!!

    2012-07-12 19:58 回復
  3. 軟件分享

    技術流!!!

    2012-07-12 19:58 回復
  4. 窮小子

    回來試試原始的評論

    2012-07-06 17:55 回復
  5. 艾倫

    嗯 不錯

    2012-07-06 14:51 回復
  6. 強哥

    剛好用上

    2012-07-06 13:10 回復

(必填)

(必填)

(可選)

黑龙江22选5开奖