SurfaceView使用实践

View之兄弟———SurfaceView

在这里插入图片描述

1.SurfaceView与View的区别

  • View通过刷新来重绘视图。Android系统通过发出VSYNC信号来绘制屏幕,刷新时间间隔为16ms.

  • 如果在16ms内完成View你所需要的操作,那么用户视觉上,就不会产生卡顿。反之,未能完成逻辑操作,就会造成画面卡顿(因此SurfaceView,这时就有用处了)

2.SurfaceView与View的适用场景

  • View主要适用主动更新的情况下,而SurfaceView适用在被动更新
  • View在主线程中对画面进行刷新,而SurfaceView会通过子线程进行UI刷新
  • VIew在绘图时没有使用双缓冲机制,而SurfaceView在底层实现机制中就已经实现了双缓冲机制

3.SurfaceView的使用

3.1 创建SurfaceView子类

​ 创建自定义的 SurfaceView 的子类, 并实现两个接口 ———SurfaceHolder.Callback和Runnable。

public class MySurfaceView extends SurfaceView 
				implements SurfaceHolder.Callback, Runnable

​ 要实现SurfaceHolder.Callabck接口方法:

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

​ 要实现Runnable接口方法:

	@Override
	public void run() {
	}
3.2 初始化SurfaceView

​ 在自定义 SurfaceView 的构造方法中,要对SurfaceView初始化。通常要先定义三个成员变量。

	//SurfaceHolder
	private SurfaceHolder holder;	
	//用于绘图的Canvas
	private Canvas canvas;
	//子线程标志
	private boolean isDrawing;

    //获取父类创建的SurfaceHolder,对holder进行初始化
    holder = getHolder();
    //注册 SurfaceHolder 的回调方法
    holder.addCallback(this);
3.3使用SurfaceView
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import static java.lang.Thread.sleep;

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable{
    //SurfaceHolder
    private SurfaceHolder holder;
    //用于绘图的Canvas
    private Canvas canvas;
    //用于绘图的画笔
    private Paint paint;
    //子线程绘制标记
    private boolean isDrawing = true;

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

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

    private void initView() {
        //获取父类创建的SurfaceHolder,对holder进行初始化
        holder = getHolder();
        //注册 SurfaceHolder 的回调方法
        holder.addCallback(this);
        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setKeepScreenOn(true);

        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        isDrawing = true;
        //子线程中绘制
        new Thread(this).start();
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder,
                               int format, int width, int height) {
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isDrawing = false;
    }

    @Override
    public void run() {
        int i = 0;
        while(isDrawing) {
            Log.d("MySurfaceView", "start draw");
            draw(i++);
        }
    }

    private void draw(int i) {
        if(i == 100) isDrawing = false;
        try {
            canvas = holder.lockCanvas();
            //绘制背景
            canvas.drawColor(Color.WHITE);
            canvas.drawCircle(250, 250, i, paint);
        } catch (Exception e) {
            Log.d("MySurfaceView", "draw() Exception");
        } finally {
            if(canvas != null)
                holder.unlockCanvasAndPost(canvas);
        }
    }
}

在这里插入图片描述

3.4正弦曲线
	@Override
	public void run() {
			draw();
			x += 1;
			y = (int)(100 * Math.sin(x * 2 * Math.PI / 180) + 400);
			path.lineTo(x, y);
	}
	private void draw() {
			try {
                canvas = holder.lockCanvas();
                //SurfaceView背景
                canvas.drawColor(Color.WHITE);
                canvas.drawPath(path, paint);
            } catch (Exception e) {
            } finally {
                if(canvas != null) {
                    holder.unlockCanvasAndPost(canvas);
            }
	}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uIZpQ8Wp-1587027364955)(Android学习.assets/SurfaceView正弦曲线.gif)]

3.5绘图板
@Override
public boolean onTouchEvent(MotionEvent event) {
    int x = (int)event.getX();
    int y = (int)event.getY();
    switch(event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            path.moveTo(x,y);
            break;
        case MotionEvent.ACTION_MOVE:
            path.lineTo(x, y);
            break;
        case MotionEvent.ACTION_UP:
            break;
    }
    return true;
}
@Override
public void run() {
    long start = System.currentTimeMillis();
    while(isDrawing) {
        draw();
    }
    long end = System.currentTimeMillis();
    //50 - 100
    if(end - start < 100) {
        try {
            //优化策略,节省系统资源
            Thread.sleep(100 - (end -start));
        } catch (InterruptException e) {
            e.printStackTrace();
        }
    }
}
private void draw() {
    try {
        canvas = holder.lockCanvas();
        canvas.drawColor(Color.WHITE);
        canvas.drawPath(path, paint);
    } catch (Exception e) {
    } finally {
        if(canvas != null) holder.unlockCanvasAndPost(canvas);
    }
}

本文摘之——《Android群英传》 P155-P161

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值