IBarrageView
interface IBarrageView {
// 弹幕是否可点击
fun setEnableTouch(enable: Boolean)
// 添加弹幕控制器
fun addController(controller: AbsBarrageController, priority: Int = 0)
// 移除弹幕控制器
fun removeController(controller: AbsBarrageController)
fun clear()
}
BarrageView
- 内部维护 List<BarrageController>
- 重写 onDraw、onTouchEvent 和 onDetachedFromWindow,进而调用 BarrageController 对应方法
class BarrageView {
override fun onDraw(canvas: Canvas) {
if (controllerList.size == 0) {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
}
loopWithIndex(controllerList.size) {
controllerList[it].apply {
draw(canvas)
}
false
}
}
override fun onTouchEvent(event: MotionEvent): Boolean {
if (mEnableTouch) {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
mTouchController = null
for (barrageController in controllerList) {
if (barrageController.onTouchEvent(event)) {
mTouchController = barrageController
return true
}
}
}
MotionEvent.ACTION_UP -> {
mTouchController?.let {
return it.onTouchEvent(event)
}
}
MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_MOVE -> {
mTouchController?.let {
return it.onTouchEvent(event)
}
}
}
return super.onTouchEvent(event)
} else {
return super.onTouchEvent(event)
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow() // 清理 Controller,防止空指针
controllerList.forEach {
it.release()
}
controllerList.clear()
}
}
AbsBarrageController
内部维护三个队列,分别为 waitingList、preparingList、runningList
内部维护计时器,通过 AnimationUpdateListener 计算时间差,并调用 onPlayBarrage 抽象方法,如果三个队列都为空,则停止计时器
abstract fun onPlayBarrage(runningList: MutableList<AbsBarrage>, deltaTime: Float)
@MainThread
private fun initAnimation(): ValueAnimator {
val animator = ValueAnimator.ofFloat(0F, AbsBarrageContr