SurfaceView绘图机制

Posted 技术丶从积累开始

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SurfaceView绘图机制相关的知识,希望对你有一定的参考价值。

一、为什么需要用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;
            }
        });
    }
View Code

 

总结整个过程

  继承SurfaceView并实现SurfaceHolder.Callback接口 ----> SurfaceView.getHolder()获得SurfaceHolder对象 ---->SurfaceHolder.addCallback(callback)添加回调函数---->SurfaceHolder.lockCanvas()获得Canvas对象并锁定画布----> Canvas绘画 ---->SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。

以上是关于SurfaceView绘图机制的主要内容,如果未能解决你的问题,请参考以下文章

史上最全SurfaceView使用讲解

史上最全SurfaceView使用讲解

Android:SurfaceView 停止在第三根手指上绘图

SurfaceView的使用

Android片段中的手电筒 - SurfaceView

Android自定义SurfaceView简单实现烟花效果