androidkotlinanimationhandlerrunnable

How to run several translate animations sequentially with ObjectAnimator?


How to run several translate animations sequentially with ObjectAnimator?

I have to animate an image like this -> from the center it moves to the left and then returns to the center, after which it must move to the right and return to the center, and then repeats the sequence endlessly, I tried to do this:

val finalizer = Runnable {
            animateCenterToLeft()
            animateCenterToRight()
        }
        Handler().postDelayed(finalizer, 0)

private fun animateCenterToLeft() {
        val finalizerR = Runnable {
            binding.logoAnimated.post {
                val point = Point()
                requireActivity().windowManager.defaultDisplay.getSize(point)
                val width = binding.logoAnimated.measuredWidth.toFloat()
                val objectAnimator = ObjectAnimator.ofFloat(
                    binding.logoAnimated,
                    "translationX",
                    0f,
                    -(width - point.x)
                )
                objectAnimator.repeatMode = ValueAnimator.REVERSE
                objectAnimator.repeatCount = 1
                objectAnimator.setDuration(10000)
                objectAnimator.start()
            }
        }
        Handler().postDelayed(finalizerR, 500)
    }

    private fun animateCenterToRight() {
        val finalizerL = Runnable {
            binding.logoAnimated.post {
                val point = Point()
                requireActivity().windowManager.defaultDisplay.getSize(point)
                val width = binding.logoAnimated.measuredWidth.toFloat()
                val objectAnimator = ObjectAnimator.ofFloat(
                    binding.logoAnimated,
                    "translationX",
                    0f,
                    +(width - point.x)
                )
                objectAnimator.repeatMode = ValueAnimator.REVERSE
                objectAnimator.repeatCount = 1
                objectAnimator.setDuration(10000)
                objectAnimator.start()
            }
        }
        Handler().postDelayed(finalizerL, 500)

    }

I expect the first animation to start first and then the second but instead only the second animation starts


Solution

  • You can use AnimatorSet to play two ObjectAnimators sequentially:

    val animator1 = ObjectAnimator.ofInt(1, 100).apply {
        repeatCount = ObjectAnimator.INFINITE
        repeatMode = ObjectAnimator.RESTART
    }
    val animator2 = ObjectAnimator.ofInt(1, 100).apply {
        repeatCount = ObjectAnimator.INFINITE
        repeatMode = ObjectAnimator.RESTART
    }
            
    val animatorSet = AnimatorSet()
    animatorSet.playSequentially(animator1, animator2)
    animatorSet.start()