You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android实现带循环间隔延迟的无限重复按钮晃动动画

实现带循环间隔延迟的无限晃动动画(避免栈溢出)

问题原因分析

第一种方案里,在doOnEnd中递归调用animator.start()会持续累积调用栈,最终触发StackOverflowError——每次动画结束后立即发起新调用,栈帧无法被回收。而你之前的AnimatorSet方案错误地给单个动画设置了无限重复,导致晃动动画一直循环,永远不会执行延迟动画。


可行方案一:使用Handler延迟触发动画

用Handler.postDelayed替代递归调用,避免栈帧累积:

val animator = ObjectAnimator
    .ofFloat(premiumButton, "translationX", 0F, 25F, -25F, 25F, -25F, 15F, -15F, 6F, -6F, 0F)
    .setDuration(2000L)

val handler = Handler(Looper.getMainLooper())
val repeatTask = object : Runnable {
    override fun run() {
        animator.start()
    }
}

animator.addListener(object : AnimatorListenerAdapter() {
    override fun onAnimationEnd(animation: Animator?) {
        // 延迟10秒后再次启动动画
        handler.postDelayed(repeatTask, 10000L)
    }
})

animator.start()

可行方案二:正确使用AnimatorSet组合动画

将晃动动画和延迟动画打包成序列,给整个AnimatorSet设置无限重复,而非单个动画:

val animatorJiggle = ObjectAnimator
    .ofFloat(myButton, "translationX", 0F, 25F, -25F, 25F, -25F, 15F, -15F, 6F, -6F, 0F)
    .setDuration(2000L)

// 创建空动画,仅用于填充10秒延迟(保持按钮在初始位置)
val animatorDelay = ObjectAnimator
    .ofFloat(myButton, "translationX", 0F)
    .setDuration(10000L)

AnimatorSet().apply {
    // 按顺序执行:晃动动画 → 延迟动画
    playSequentially(animatorJiggle, animatorDelay)
    // 给整个序列设置无限重复
    repeatCount = ObjectAnimator.INFINITE
    start()
}

内容的提问来源于stack exchange,提问作者Lifes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 05:15:45