(原创)SurfaceView介绍和使用

本文介绍如何使用Android的SurfaceView解决复杂的UI绘制问题,避免主线程阻塞导致的界面卡顿,通过示例代码展示了SurfaceView的基本用法及关键生命周期回调。

我们都知道

Android中是在主线程绘制UI的

如果我们可以在16ms以内将绘制工作完成

那么将没有问题

但如果我们绘制过程逻辑很复杂,

并且我们的界面更新还非常频繁,

这时候就会造成界面的卡顿,影响用户体验,

为此Android提供了SurfaceView来解决这一问题。

SurfaceView 一方面可以实现复杂而高效的UI,

另一方面又不会导致用户输入得不到及时响应。

下面用一个简单的示例来展示用法

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
    //SurfaceHolder
    private SurfaceHolder mHolder;
    //用于绘图的Canvas
    private Canvas mCanvas;
    //子线程标志位
    private boolean mIsDrawing;


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

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

    }

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

    }

    private void initView() {
        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() {
        long start = System.currentTimeMillis();
        while (mIsDrawing) {
            draw();
            long end = System.currentTimeMillis();
            if (end - start < 100) {
                try {
                    long sj = 100 - end + start;
                    Thread.sleep(sj);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void draw() {

        try {
            //锁定画布并返回画布对象
            mCanvas = mHolder.lockCanvas();


            //todo 1执行实际绘制

            //todo 2执行回调方法
            if (listener!=null){
                listener.backChangeListener();
            }

        } catch (Exception e) {
        } finally {
            //当画布内容不为空时,才post,避免出现黑屏的情况。
            if (mCanvas != null)
                mHolder.unlockCanvasAndPost(mCanvas);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }

    private OnbackChangeListener listener;

    public void setOnbackChangeListener(OnbackChangeListener listener) {
        this.listener = listener;
    }

    public interface OnbackChangeListener {
        //回调方法
        void backChangeListener();
    }
}

这是一个自定义的SurfaceView

可以看到,有三个具体的方法

surfaceCreated

surfaceChanged

surfaceDestroyed

分别是在SurfaceView创建,尺寸改变,销毁时调用

我们在创建的时候开启一个子线程

里面进行核心UI界面的绘制

另外还新增了一个接口回调方法

用来在绘制完成后回调

注意

回调的方法里

可以通过Handler

或者

runOnUiThread

回到主线程进行一些业务逻辑

这里就没有具体写上去了

具体的业务逻辑,

在这个类里面进行补充即可

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值