首页 > 解决方案 > 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 不能正常工作!!

这是 Galaxy Note 中的问题 在此处输入图像描述

这就是我想要在旧小米手机上工作的东西。 在此处输入图像描述

标签: androidanimation

解决方案


我解决了。

像下面一样更改TypeEvaluator

val paintEvaluator = TypeEvaluator<Paint> { fraction, _, _ ->

        when(fraction) {
            1f -> inactivePaint
            0f -> inactivePaint
            else -> activePaint
        }
    }

推荐阅读