类似Npc说话的TextView
class NpcTextView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AppCompatTextView(context, attrs, defStyleAttr), DefaultLifecycleObserver {
private var mPrintString: String? = null
private var mPrintAnimator: ValueAnimator? = null
var mPerTextSpeed = 50L
/**
* 帮生命周期监听
*
*/
fun addLifecycleObserver(owner: LifecycleOwner) {
owner.lifecycle.addObserver(this)
}
/**
* 开始显示文字
*
*/
fun printText(str: String?) {
if (str.isNullOrEmpty()) {
return
}
if (mPrintAnimator?.isRunning == true) {
clear()
}
mPrintString = str
// 字符串的长度
val length = str.length
val charArray = CharArray(length)
//将字符串转换成字符数组
for (i in 0 until length) {
charArray[i] = str[i]
}
mPrintAnimator = ValueAnimator.ofFloat(0f, 1f).apply {
val printDuration = length * mPerTextSpeed
duration = printDuration
addUpdateListener { animation ->
// 字体显示的速度 v = 总的字体长度 / 总的显示时间
val v = length.toFloat() / printDuration.toFloat()
// 动画执行速度
val fraction = animation.animatedValue as Float
//动画不同阶段字体应该显示的个数
val s = (v * fraction * printDuration).toInt()
setText(charArray, 0, s)
}
}
mPrintAnimator?.start()
}
fun getPrintText() = mPrintString ?: ""
override fun onPause(owner: LifecycleOwner) {
super.onPause(owner)
clear()
text = mPrintString
}
fun clear() {
mPrintAnimator?.removeAllListeners()
mPrintAnimator?.removeAllUpdateListeners()
mPrintAnimator?.cancel()
text = ""
}
}