一、为什么需要用SurfaceView绘图,不直接继承View绘图
它的特性是:可以在主线程之外的线程中向屏幕绘图上。这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView。
二、SurfaceView类的机制
1.简单机制:详见"Camera实现预览、拍照"
2.绘图机制主要方法:
(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); // 结束锁定画图,并提交改变。
注意:当SurfaceHolder的unlockCanvasAndPost()被调用时,下一次lockCanvas()锁定的区域会遮挡该部分(就是新锁定的Canvas在旧Canvas的上面)
实例:
private SurfaceHolder mSurfaceHolder; private int mColor = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //在res/activity_main中创建了SurfaceView控件 SurfaceView surfaceView = (SurfaceView) findViewById(R.id.main_surfaceView); //获取SurfaceHolder类 mSurfaceHolder = surfaceView.getHolder(); //回调Surface的生命周期 mSurfaceHolder.addCallback(new SurfaceHolder.Callback() { //当被创建的时候显示 @Override public void surfaceCreated(SurfaceHolder holder) { //获取Surface上的Canvas Canvas canvas = mSurfaceHolder.lockCanvas(); Paint paint = new Paint(); //获取res/mipmap下的图片 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.room); canvas.drawBitmap(bitmap,0,0,paint); //保存并提交canvas画的内容 holder.unlockCanvasAndPost(canvas); } //当Surface大小、格式改变的时候回调。首次显示在屏幕上调用。参数是Surface的像素格式、宽、高 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } //当Surface被销毁的时候显示 @Override public void surfaceDestroyed(SurfaceHolder holder) { } }); //创建点击事件 surfaceView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: //获取点击的X,Y int currentX = (int)event.getX(); int currentY = (int)event.getY(); Paint paint = new Paint(); //双数方块为RED,单数方块为GREEN if (mColor%2 == 0) { paint.setColor(Color.RED); }else { paint.setColor(Color.GREEN); } ++mColor; //锁定Surface上的Rect划分的一块区域 Rect rect = new Rect(currentX-50,currentY-50,currentX+50,currentY+50); Canvas canvas = mSurfaceHolder.lockCanvas(rect); canvas.drawRect(rect,paint); mSurfaceHolder.unlockCanvasAndPost(canvas); break; } return true; } }); }
总结整个过程
继承SurfaceView并实现SurfaceHolder.Callback接口 ----> SurfaceView.getHolder()获得SurfaceHolder对象 ---->SurfaceHolder.addCallback(callback)添加回调函数---->SurfaceHolder.lockCanvas()获得Canvas对象并锁定画布----> Canvas绘画 ---->SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。