如何实现无渐变的TextView闪烁动画?Kotlin代码优化求助
优化方案:实现无渐变的TextView闪烁动画
原来的AlphaAnimation会在指定时长内平滑过渡透明度,因此产生了渐变淡入淡出效果。要实现瞬时切换透明度的无渐变闪烁,推荐使用ValueAnimator直接控制View的alpha属性,精准实现状态的瞬间切换:
private fun View.blink( times: Int = ValueAnimator.INFINITE, holdDuration: Long = 400L, // 每个透明度状态的停留时长 offset: Long = 20L, minAlpha: Float = 0.0f, maxAlpha: Float = 1.0f ) { var currentAlpha = maxAlpha val animator = ValueAnimator.ofFloat(currentAlpha, currentAlpha).apply { duration = holdDuration startDelay = offset repeatCount = times addListener(object : Animator.AnimatorListener { override fun onAnimationStart(animation: Animator?) {} override fun onAnimationEnd(animation: Animator?) {} override fun onAnimationCancel(animation: Animator?) {} override fun onAnimationRepeat(animation: Animator?) { // 每次重复时瞬时切换透明度 currentAlpha = if (currentAlpha == maxAlpha) minAlpha else maxAlpha alpha = currentAlpha } }) } // 初始化显示状态 alpha = maxAlpha animator.start() }
核心逻辑说明
- 放弃依赖
AlphaAnimation的渐变插值逻辑,改用ValueAnimator触发状态切换时机 - 通过
onAnimationRepeat回调在每个周期结束时瞬时切换alpha属性,完全跳过渐变过程 holdDuration控制每个透明度状态的停留时间,比如设为400L时,会呈现“显示400ms→隐藏400ms”的无闪烁渐变效果
如果想要更轻量化的实现,也可以用简化版的ValueAnimator反向模式:
private fun View.blink( times: Int = ValueAnimator.INFINITE, holdDuration: Long = 400L, offset: Long = 20L, minAlpha: Float = 0.0f, maxAlpha: Float = 1.0f ) { ValueAnimator.ofFloat(maxAlpha, minAlpha).apply { duration = holdDuration startDelay = offset repeatCount = times repeatMode = ValueAnimator.REVERSE // 设置插值器为线性,确保切换瞬时完成 interpolator = LinearInterpolator() addUpdateListener { animator -> alpha = animator.animatedValue as Float } start() } }
为什么替换原有实现?
AlphaAnimation的设计目标是实现透明度渐变,即使将时长设为0,其内部插值逻辑也会导致过渡不够彻底。而直接修改View的alpha属性,能做到真正的瞬时状态切换,完全符合无渐变闪烁的需求。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

