SurfaceView的一些事

2018-06-24  本文已影响0人  懒猫1105

SurfaceView的一些事

1.为什么Android设计了SurfaceView

View可以满足大部分需求,但是在某些特殊时候也力不从心。
因为View是通过刷新来重绘视图,Android系统通过发出VSYNC信号来进行屏幕绘制,刷新间隔时间为16ms。
如果16ms内view完成了绘制过程,那么用户在视觉上不会感到卡顿。
但是在绘制过程中有太多的逻辑需要处理,16ms内无法完成绘制的时候,就需要SurfaceView来解决这一问题。

2.View与SurfaceView的区别
3.SurfaceView的使用

模板代码

//继承SurfaceView 类,实现SurfaceHolder.Callback 和 Runnable 接口
public abstract class SurfaceViewTemplate extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    //定义以下三个成员变量
    private SurfaceHolder mHolder;  //SurfaceHolder
    private Canvas mCanvas;         //用于绘制的Canvas
    private boolean mIsDrawing;     //子线程绘制标志位

    public SurfaceViewTemplate(Context context) {
        super(context);
        initView();
    }

    public SurfaceViewTemplate(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    //初始化
    private void initView() {
        mHolder = getHolder();
        mHolder.addCallback(this);
        setFocusable(true);
        setFocusableInTouchMode(true);
        setKeepScreenOn(true);
        onInit(mHolder);
    }

    //初始化时候回调
    protected abstract void onInit(SurfaceHolder holder);

    //当SurfaceView创建的时候,开启子线程进行绘制操作
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mIsDrawing = true;
        new Thread(this).start();
    }

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

    }

    //当SurfaceViewDestroy时候停止绘制操作
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mIsDrawing = false;
    }

    private void draw() {
        try {
            mCanvas = mHolder.lockCanvas();
            realDraw(mCanvas);
        } catch (Exception e) {
            onError(e);
        } finally {
            if (mCanvas != null) {
                mHolder.unlockCanvasAndPost(mCanvas);
            }
        }
    }

    //循环进行绘制流程
    @Override
    public void run() {
        
        while (mIsDrawing) {
            beforeDraw();
            draw();
            afterDraw();
        }
        
    }

    //绘制之前回调
    protected abstract void beforeDraw();

    //绘制完毕回调
    protected abstract void afterDraw();

    //真正的绘制一些东西
    protected abstract void realDraw(Canvas canvas);

    //绘制时候发生异常回调
    protected abstract void onError(Exception e);
}

绘画板Demo

public class DrawingBoardView extends SurfaceViewTemplate {

    public DrawingBoardView(Context context) {
        super(context);
    }

    public DrawingBoardView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DrawingBoardView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private Paint mPaint;

    private Path mPath;

    @Override
    protected void onInit(SurfaceHolder holder) {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        mPath = new Path();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mPath.moveTo(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                mPath.lineTo(x, y);
                break;
        }
        return true;
    }

    @Override
    protected void beforeDraw() {

    }

    @Override
    protected void afterDraw() {

    }

    @Override
    protected void realDraw(Canvas canvas) {
        //canvas默认保存了上一次绘制的内容
        //所以这里清空一下,重新开始绘制
        canvas.drawColor(Color.WHITE);
        //绘制路径
        canvas.drawPath(mPath, mPaint);
    }

    @Override
    protected void onError(Exception e) {

    }
}

上一篇 下一篇

猜你喜欢

热点阅读