View 和 SurfaceView的區別

這裏說的是在繪圖中二者的區別:java

1View在繪圖中,重寫onDraw(Canvas canvas)方法,經過invaldate()和pastInvalidate()兩個方法進行從新繪製畫布;canvas

invalidate()不能再本身建立的線程中循環調用;ide

postInvalidate()能夠在本身建立的線程中循環調用執行。若是不在當前View 建立線程循環重繪畫布的話,這兩種重繪畫布的函數就沒什麼區別了,均可以用。函數

public class MyView extends View {

	private float x;
	private float y;
	public MyView(Context context) {
		super(context);
	}

	
	//須要繪製圖像時調用
	@Override
	protected void onDraw(Canvas canvas) {
		Paint mPaint = new Paint();
		mPaint.setColor(Color.BLUE);
		canvas.drawLine(0, 0, x, y, mPaint);
		super.onDraw(canvas);
		
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		x = event.getX();
		y = event.getY();
		//重繪畫布
		invalidate();
//		postInvalidate();
		return true;
		
	}
}

2,surfaceView繼承自viewpost

在使用surfaceView時,你會發現複寫父類的onDraw(Canvas canvas)方法並不會執行。緣由是在SurfaceView中,咱們並不會直接跟他打交道,而是經過SurfaceHolder來控制。使用SurfaceHolder的lockCanvas()函數來獲取到SurfaceView的Canvas對象,再經過Canvas上繪製內容來修改SurfaceView中的數據this

public class MySurfaceView extends SurfaceView implements Callback, Runnable {

	private SurfaceHolder sfh;
	private Paint paint;
	private Canvas canvas;

	private Thread th;
	private boolean flag;
	private int textX;
	private int textY;

	public MySurfaceView(Context context) {
		super(context);
		sfh = this.getHolder();
		sfh.addCallback(this);
		paint = new Paint();
		paint.setColor(Color.WHITE);
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		flag = true;
		th = new Thread(this);
		th.start();
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		flag = false;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		textX = (int) event.getX();
		textY = (int) event.getY();
		return true;
	}

	public void myDraw() {
		// 獲取一個加鎖的畫布,爲了防止surfaceview在繪製過程當中被修改,銷燬等情況
		Paint blackPaint = new Paint();
		blackPaint.setColor(Color.BLACK);
		
		try {
			canvas = sfh.lockCanvas();
			if (canvas != null) {
				canvas.drawRect(0, 0, getWidth(), getHeight(), blackPaint);// 刷屏1
//			canvas.drawColor(Color.BLACK);//刷屏2
//			canvas.drawRGB(0, 0, 0);//刷屏3
				canvas.drawText("game", textX, textY, paint);

			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if (canvas != null) {
				// 解鎖畫布和提交
				sfh.unlockCanvasAndPost(canvas);
			}
			
		}

	}

	/**
	 * 遊戲邏輯
	 */
	private void logic() {

	}

	@Override
	public void run() {
		while (flag) {
			long start = System.currentTimeMillis();
			myDraw();
			logic();
			long end = System.currentTimeMillis();
			try {
				if (end - start < 50) {
					Thread.sleep(50 - (end - start));
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

他們兩個更新畫布的區別:線程

在View視圖中對於畫布的從新繪製,是經過調用View 提供的postInvalidate()與inValidate()這兩個函數來執行的,也就是說畫布是由系統主UI進行更新。那麼當系統主UI線程被繪製函數阻塞,這樣一來則會引起沒法響應按鍵,觸屏等消息的問題;code

SurfaceView視圖中對於畫布的重繪是由一個新的單獨線程去執行處理,因此不會出現因主UI線程阻塞而致使沒法響應按鍵,觸屏信息等問題。orm


surfaceview 有雙緩衝機制,而view 沒有
對象

相關文章
相關標籤/搜索