SurfaceView的代码模板

Posted 春招进大厂的梦想家

tags:

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

🍨SurfaceView的代码模板

🎏说在前面的:屋外是无尽的寒风,屋里是可亲的人。寒风想吹灭的你的光亮,你的任务是照亮这间小小的屋子。加油吧

1.SurfaceView 与 View的区别

  • 使用View的痛点:

    • View通过刷新来重绘视图,android系统通过发出了VSYNC的信号来进行屏幕的绘制,刷新的时间间隔为16ms,如果在此时间内没有完成刷新操作,用户体验就会卡顿;
  • View主要适用于主动更新的情况,而SurfaceView主要适用于被动更新,例如频繁的刷新;

  • View在主线程中对画面进行刷新,而SURfaceView通常通过一个子线程来进行页面的刷新;

  • View在绘制的时候会使用双缓存机制,而SurfaceView在底层实现机制中已经实现了双缓存机制;

📝总结成一句话就是:如果你的自定义view需要频繁的刷新,或者刷新是数据量比较大,可以考虑使用SurfaceView;

2.SurfaceView的使用:

(1)创建SurfaceView

public class SurfaceView_eg extends SurfaceView implements SurfaceHolder.Callback,Runnable

(2)初始化SurfaceView

//syrfaceHolder
    private SurfaceHolder mHolder;
    //用于绘图的Canvas
    private Canvas mCanvas;
    //子线程标志位
    private boolean mIsDrawing;
    private int x;
    private int y;


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

(3)使用SurfaceView(全部代码)

package com.example.android_wavebackground;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import androidx.annotation.NonNull;

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

    //syrfaceHolder
    private SurfaceHolder mHolder;
    //用于绘图的Canvas
    private Canvas mCanvas;
    //子线程标志位
    private boolean mIsDrawing;
    private int x;
    private int y;

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

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

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

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

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        mIsDrawing = true;
        new Thread(this).start();
    }

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

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
        mIsDrawing = false;
    }

    @Override
    public void run() {
        while (mIsDrawing) {
            draw();
        }
    }
    /*
     mHolder.unlockCanvasAndPost(mCanvas);放在finally中的目的是保证每次都能将内容提交
     */
    private void draw(){
        try {
            mCanvas = mHolder.lockCanvas();
        }catch (Exception e){

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

3.零碎小知识点

(1)SurfaceView的创建、改变、销毁

 @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
       
    }

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

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
        
    }

上面的三个方法分别对应SurfaceView的创建、改变、销毁的过程.

(2)绘制的几个知识点

绘制的时候,充分利用SurfaceView的三个回调方法,在SurfaceCreated()中开启一个子线程进行绘制,而子线程使用一个while()循环来不停进行绘制;

通过lockCanvas()方法获得的Canvas对象进行绘制,并通过unlockCancasAndPost()方法来对画布的内容进行提交.

以上是关于SurfaceView的代码模板的主要内容,如果未能解决你的问题,请参考以下文章

Android片段中的手电筒 - SurfaceView

丑陋的片段过渡到带有覆盖的surfaceview

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段2——.vue文件的模板

VSCode自定义代码片段1——vue主模板

VSCode自定义代码片段(vue主模板)