android - Android 动画重复无法正常工作
问题描述
我在 Drawable 上重复制作了一些 Animator。它在第一次工作,但从第二次开始不起作用。
ChProgressBar.class
class ChProgressBar(context: Context, attrs: AttributeSet): View(context, attrs) {
private var dotCount = 3
private var dotRadius = 65f
private var dotInterval = 20f
private val activePaint = Paint()
private val inactivePaint = Paint()
private val dotList = mutableListOf<DotDrawable>()
init {
context.theme.obtainStyledAttributes(attrs, R.styleable.ChProgressBar, 0, 0).let {
try {
dotCount = it.getInt(R.styleable.ChProgressBar_dotCount, 3)
dotRadius = it.getDimension(R.styleable.ChProgressBar_dotDiameter, 130f) / 2
dotInterval = it.getDimension(R.styleable.ChProgressBar_dotInterval, 20f)
activePaint.color = it.getColor(R.styleable.ChProgressBar_activeColor, Color.BLACK)
inactivePaint.color = it.getColor(R.styleable.ChProgressBar_inactiveColor, Color.WHITE)
} finally {
it.recycle()
}
}
for (i in 0 until dotCount) {
dotList.add(DotDrawable(dotRadius, inactivePaint))
}
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
dotList.forEach { it.draw(canvas) }
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
adjustDotBounds(measuredWidth, measuredHeight)
}
private fun adjustDotBounds(width: Int, height: Int) {
val diameter = (dotRadius * 2).toInt()
val totalDotWidth = (diameter*dotCount + dotInterval*(dotCount-1)).toInt()
val diameterWithInterval = (diameter + dotInterval).toInt()
val paddingStart = (width - totalDotWidth)/2f
var left = paddingStart.toInt()
var right = left + diameter
dotList.forEach {
// adjust as if 'setGravity' center
it.setBounds(left, 0, right, height)
left += diameterWithInterval
right += diameterWithInterval
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
createAnimation()
}
private fun createAnimation() {
val paintEvaluator = TypeEvaluator<Paint> { _, _, endValue ->
endValue
}
val animatorList = mutableListOf<Animator>()
dotList.forEach { dot ->
val animator = ObjectAnimator.ofObject(dot, "paint", paintEvaluator, inactivePaint, activePaint, inactivePaint)
animator.apply {
duration = 250
startDelay = 500
addUpdateListener { invalidate() }
}
animatorList.add(animator)
}
val animatorSet = AnimatorSet()
animatorSet.apply {
playSequentially(animatorList)
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
start()
}
})
start()
}
}
DotDrawable.class
class DotDrawable(private val radius: Float,
var paint: Paint) : Drawable() {
override fun draw(canvas: Canvas) {
canvas.drawCircle(bounds.exactCenterX(), bounds.exactCenterY(), radius, paint)
}
override fun setAlpha(alpha: Int) {}
override fun setColorFilter(colorFilter: ColorFilter?) {}
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
}
我已经测试了几台设备,一部旧的小米手机可以正常工作,但是 Galaxy Note 10 和 Galaxy Not 8 不能正常工作!!
解决方案
我解决了。
像下面一样更改TypeEvaluator
val paintEvaluator = TypeEvaluator<Paint> { fraction, _, _ ->
when(fraction) {
1f -> inactivePaint
0f -> inactivePaint
else -> activePaint
}
}
推荐阅读
- android - 如何创建自定义背景
- reactjs - 使用箭头键在嵌套列表中导航 ReactJS
- c# - EF Core 级联删除以提高速度?
- paxos - 是什么决定了 Paxos 中的角色?
- amazon-web-services - Amazon RDS 成本节约建议
- javascript - 如何在 Material Design Lite 中动态加载的 Select 中预先选择一个值?
- vnc-server - x11vnc 在 CentOs 7.2 上因“检测到缓冲区溢出”而失败
- office-js - Outlook Web 加载项调用 Microsoft Graph
- php - WooCommerce wc_update_product_stock 将数字作为十进制存储在数据库中
- php - 尝试登录旧代码时 PDO 不起作用