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 没有
对象

相关文章
相关标签/搜索