欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SurfaceView

程序员文章站 2022-03-29 19:30:14
...

1.为什么用SurfaceView:SurfaceView比View更适用于频繁刷新,surfaceview通常会通过一个子线程来进行页面刷新,View会直接在主线程中对画面进行刷新。所以当我们的自定义View需要频繁刷新,或者刷新时数据处理量比较大就可以考虑使用surfaceview来代替View。

2.模版:

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable{

    private SurfaceHolder mHolder;
    private Canvas mCanvas;
    private boolean mIsDrawing;



    public MySurfaceView(Context context) {
        this(context,null);
    }

    public MySurfaceView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

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

    private void init() {

        mHolder = getHolder();
        mHolder.addCallback(this);
        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setKeepScreenOn(true);


    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        mIsDrawing = true;
        new Thread(this).start();

    }

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

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

        mIsDrawing = false;
    }

    @Override
    public void run() {

        while (mIsDrawing){

            draw();

        }
    }

    private void draw(){

        try {
            mCanvas = mHolder.lockCanvas();


        }catch (Exception e){


        }finally {
            if(mCanvas!=null){
                mHolder.unlockCanvasAndPost(mCanvas);
            }
        }


    }




}

3.正弦曲线:

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable{

    private SurfaceHolder mHolder;
    private Canvas mCanvas;
    private boolean mIsDrawing;



    public MySurfaceView(Context context) {
        this(context,null);
    }

    public MySurfaceView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

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

    int x;
    int y;
    Path mPath;
    Paint mPaint;
    private void init() {

        mHolder = getHolder();
        mHolder.addCallback(this);
        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setKeepScreenOn(true);
        mPath = new Path();
        mPaint = new Paint();
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(10);

    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        mIsDrawing = true;
        new Thread(this).start();

    }

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

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

        mIsDrawing = false;
    }

    @Override
    public void run() {



        while (mIsDrawing){

            draw();
            x+=1;
            y = (int) (100*Math.sin(x*2* Math.PI/180)+400);
            mPath.lineTo(x,y);

        }



    }


//    @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;
//
//            case MotionEvent.ACTION_UP:
//
//
//                break;
//        }
//
//
//        return true;
//    }

    private void draw(){

        try {
            mCanvas = mHolder.lockCanvas();
            mCanvas.drawColor(Color.WHITE);
            mCanvas.drawPath(mPath,mPaint);

        }catch (Exception e){


        }finally {
            if(mCanvas!=null){
                mHolder.unlockCanvasAndPost(mCanvas);
            }
        }


    }




}

3.画板

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable{

    private SurfaceHolder mHolder;
    private Canvas mCanvas;
    private boolean mIsDrawing;



    public MySurfaceView(Context context) {
        this(context,null);
    }

    public MySurfaceView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

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

    int x;
    int y;
    Path mPath;
    Paint mPaint;
    private void init() {

        mHolder = getHolder();
        mHolder.addCallback(this);
        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setKeepScreenOn(true);
        mPath = new Path();
        mPaint = new Paint();
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(10);

    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        mIsDrawing = true;
        new Thread(this).start();

    }

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

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

        mIsDrawing = false;
    }

    @Override
    public void run() {



        while (mIsDrawing){

            draw();
//            x+=1;
//            y = (int) (100*Math.sin(x*2* Math.PI/180)+400);
//            mPath.lineTo(x,y);

        }



    }


    @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;

            case MotionEvent.ACTION_UP:


                break;
        }


        return true;
    }

    private void draw(){

        try {
            mCanvas = mHolder.lockCanvas();
            mCanvas.drawColor(Color.WHITE);
            mCanvas.drawPath(mPath,mPaint);

        }catch (Exception e){


        }finally {
            if(mCanvas!=null){
                mHolder.unlockCanvasAndPost(mCanvas);
            }
        }


    }




}

如果把onTouchEvent的return值改成false或者super就什么都画不出来。super最后结果也是false因为该View并不是clickble所以会返回false,所以问题就是返回false为什么就画不出来了。

之前的困惑:虽然该View并没有消耗这个事件,但是执行了我们重写的ontouchEvent方法,执行了actionDown和actionMove,也就执行mPath.moveTo(x,y);和mPath.lineTo(x,y),理论上来说虽然没有消耗这个事件但是应该有图像。

后来仔细的思考了一下:在actionDown的时候事件没有消耗,之后的move事件就不会走,而我们重写的onTouchEvent方法中的actionDown只有mPath.moveTo(x,y)这个并不会画上去,所以不显示

 

上一篇: surfaceview

下一篇: SurfaceView