How to repeat Android Animation

Viewed 182

I'm trying to get two views to move to the middle of the screen and bounce back again x number of times.

This code does that but it runs only once. ` val view = findViewById(R.id.imageView2)

    val animation = SpringAnimation(view, DynamicAnimation.TRANSLATION_Y, 0f)

    val view2 = findViewById<View>(R.id.imageView3)
    val animation2 = SpringAnimation(view2, DynamicAnimation.TRANSLATION_Y, 0f)

    findViewById<View>(R.id.imageView2).also { img ->
        SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {

            animation.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_HIGH_BOUNCY)

          
            animation.spring.stiffness = SpringForce.STIFFNESS_VERY_LOW

                animation.animateToFinalPosition(50f)
            

        }
    }
    findViewById<View>(R.id.imageView3).also { img ->
        SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
            
            animation2.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_HIGH_BOUNCY)

            
            animation2.spring.stiffness = SpringForce.STIFFNESS_VERY_LOW
           
            animation2.animateToFinalPosition(-100f)
            

        }
    }`

So how do I get it to run x number of times? This is obviously Spring Animation, but I'm not married to it. If there is another animation that would accomplish this I'd be totally open to changing.

2 Answers

Set android:repeatCount="infinite" in anim folder

You can run multiple SpringAnimations on the same View by repeatedly calling animateToFinalPosition(translation) with a sequence of translation values.

For example:

startSpringAnimations(findViewById<View>(R.id.imageView1), 300f, 6)
startSpringAnimations(findViewById<View>(R.id.imageView2), -600f, 6)

with a function

/**
 * [view] will be moved using [times] SpringAnimations over a distance of abs([totalTranslation])
 * If [totalTranslation] is negative, direction will be up, else down
 */
private fun startSpringAnimations(view: View, totalTranslation: Float, times: Int ) {
    if(times <= 0){
        return
    }

    val translation = totalTranslation/ times.toFloat()

    SpringAnimation(view, DynamicAnimation.TRANSLATION_Y, 0f).apply{
        spring.dampingRatio = SpringForce.DAMPING_RATIO_HIGH_BOUNCY
        spring.stiffness = SpringForce.STIFFNESS_VERY_LOW

        addEndListener(object: DynamicAnimation.OnAnimationEndListener{
            private var count = 1
            override fun onAnimationEnd(animation1: DynamicAnimation<*>?, canceled: Boolean, value: Float, velocity: Float) {
                Log.d("SpringAnimation", "onAnimationEnd: animation $animation1 canceled $canceled value $value velocity $velocity count $count")
                if (canceled) return

                count++
                if(count <= times){
                    animateToFinalPosition(translation * count)
                }
            }
        })
        animateToFinalPosition(translation)
    }
}
Related