我正在分解一个Android应用,其中我有一个无限重复的动画,这会引起StackOverflowError。当在同一对象上启动另一个动画时,便会执行此操作。
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()
}
}
我尝试将函数更改为fun pulse(stop: boolean)
,在其他动画开始之前调用pulse(false)
以启动脉冲,并调用pulse(true)
,然后在多个位置添加if (stop) {soulToButton.cancel()}
。我还尝试将导致错误的行换行,例如:while(stop == false){soultoButton.start()}
所有这些都无济于事。
答案 0 :(得分:3)
尝试使用此版本:它简短明了,基本上在做同样的事情。
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()
}
答案 1 :(得分:2)
它是Kotlin,但它仍然是Java,并且所有JVM限制都与此处有关。因此,由于JVM堆栈受到限制,因此不能无限期地调用一个函数而不会引起StackOverflowError。
有一些特殊功能可以帮助您无限期地运行动画。例如
objectAnimator.setRepeatCount(ObjectAnimator.INFINITE);
或者就您而言
ObjectAnimator.ofFloat(mContentView, "scaleX", 1.3f).apply {
duration = durationx.toLong()
repeatCount = ObjectAnimator.INFINITE
}
以相同方式修改所有动画并将其链接到AnimatorSet
后,其start
函数将无限期播放此动画,而不会出现StackOverflowError。
希望有帮助。
答案 2 :(得分:0)
您正在尝试在此处完成动画之后再次开始动画,
soulToButton.addListener(object: AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
soulToButton.start() // This will start the animation again without an end to the animation hence the StackOverflow error.
}
})
为了无限期地运行动画,请使用以下代码,
val inflateX = ObjectAnimator.ofFloat(mContentView, "scaleX", 1.3f).apply {
duration = durationx.toLong()
repeatCount = ObjectAnimator.INFINITE
}
val soulToButton = AnimatorSet().apply {
play(inflateX).with(inflateY)
play(rotate).with(inflateX)
play(deflateX).after(inflateX)
play(deflateY).after(inflateY)
}
soulToButton.start()