package com.netease.nim.uikit.common.ui.barrage;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
* SurfaceView 任务队列驱动/间隔绘制模板
* Created by huangjun on 2016/5/8.
*/
public abstract class SurfaceViewTemplate extends SurfaceView implements SurfaceHolder.Callback, Runnable {
private SurfaceHolder mHolder;
private Canvas canvas;
private boolean isRunning;
private final Object lock = new Object();
public SurfaceViewTemplate(Context context) {
this(context, null);
}
public SurfaceViewTemplate(Context context, AttributeSet attrs) {
super(context, attrs);
mHolder = getHolder();
mHolder.addCallback(this);
// 设置Surface在Window(普通视图架构)之上
setZOrderOnTop(true);
// 设置色彩格式,半透明
mHolder.setFormat(PixelFormat.TRANSLUCENT);
// 设置可获得焦点
setFocusable(true);
setFocusableInTouchMode(true);
// 设置保持屏幕亮
this.setKeepScreenOn(true);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
isRunning = true;
new Thread(this).start(); // 开启线程
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
notifyHasTask(); // 释放锁
isRunning = false; // 通知关闭线程
}
@Override
public void run() {
while (isRunning) {
try {
// 判断是否还有绘制任务,任务队列空可以先wait,等待任务唤醒
synchronized (lock) {
if (!hasTask()) {
lock.wait();
}
}
// 执行绘制任务
draw();
// 控制绘制的时间间隔
Thread.sleep(getRunTimeInterval());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void draw() {
try {
// get canvas
canvas = mHolder.lockCanvas(); // 如果SurfaceView不在前台,这里会阻塞
if (canvas != null) {
// clear screen
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
// do draw task
onDrawView(canvas);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null)
mHolder.unlockCanvasAndPost(canvas);
}
}
/**
* 执行绘制任务
*/
protected abstract void onDrawView(Canvas canvas);
/**
* 绘制任务执行间隔
*/
protected abstract int getRunTimeInterval();
/**
* 是否有绘制任务
*/
protected abstract boolean hasTask();
protected void notifyHasTask() {
synchronized (lock) {
lock.notify();
}
}
}