Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looping an AnimationSet causes StackOverflowError

I am delevolping an android app in which I have an infinitely repeating animation that is causing a StackOverflowError. It does this, when another animation on the same object is started.

private fun pulse() {
    val randomGenerator = Random()

    val durationx = randomGenerator.nextInt(4000) + 1500

    val inflateX = ObjectAnimator.ofFloat(mContentView, "scaleX", 1.3f).apply {
        duration = durationx.toLong()
    }
    val inflateY = ObjectAnimator.ofFloat(mContentView, "scaleY", 1.3f).apply {
        duration = durationx.toLong()
    }
    val deflateX = ObjectAnimator.ofFloat(mContentView, "scaleX", 1.0f).apply {
        duration = durationx.toLong()
    }
    val deflateY = ObjectAnimator.ofFloat(mContentView, "scaleY", 1.0f).apply {
        duration = durationx.toLong()
    }
    val rotate = ObjectAnimator.ofFloat(mContentView, "rotation", 1.0f).apply {
        duration = durationx.toLong()
    }
    val soulToButton = AnimatorSet().apply {
        play(inflateX).with(inflateY)
        play(rotate).with(inflateX)
        play(deflateX).after(inflateX)
        play(deflateY).after(inflateY)
        start()
    }

    soulToButton.addListener(object: AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            super.onAnimationEnd(animation)
            soulToButton.start() // stacktrace points to this line as cause for the error.
        }
    })
    soulToButton.start()

    AnimatorSet().apply {
        play(soulToButton)
        start()
    }
}

I tried changing the function to fun pulse(stop: boolean), calling pulse(false) for starting the pulse and pulse(true) before the other animation starts, and adding if (stop) {soulToButton.cancel()} in several places. I also tried wrapping the line causing the error like this: while(stop == false){soultoButton.start()}

All of this didn´t help.

like image 462
BraveSentry Avatar asked Sep 13 '25 04:09

BraveSentry


1 Answers

Try out this version: its short and concise and basically doing the same thing.

    val randomGenerator = Random()

    val durationx = randomGenerator.nextInt(4000) + 1500

    val animator = animator@{ property : String, value : Float ->
        return@animator ObjectAnimator.ofFloat(mContextView, property, value).apply {
            duration = durationx.toLong()
            repeatMode = REVERSE
            repeatCount = INFINITE
        }
    }

    AnimatorSet().apply {
        playTogether(animator("scaleX", 1.3f),animator("scaleY", 1.3f),animator("rotation", 45.0f))
        start()
    }
like image 165
Rahul Sharma Avatar answered Sep 15 '25 19:09

Rahul Sharma