方案1:属性动画(推荐)
最稳定高效的实现方式
class PulseAnimator private constructor() {
private var animator: ValueAnimator? = null
companion object {
fun applyTo(view: View): PulseAnimator {
return PulseAnimator().apply { start(view) }
}
}
fun start(view: View) {
stop()
animator = ValueAnimator.ofFloat(1f, 1.2f).apply {
duration = 800
repeatCount = ValueAnimator.INFINITE
repeatMode = ValueAnimator.REVERSE
interpolator = AccelerateDecelerateInterpolator()
addUpdateListener {
val scale = it.animatedValue as Float
view.scaleX = scale
view.scaleY = scale
}
}
animator?.start()
}
fun stop() {
animator?.let {
it.cancel()
it.removeAllUpdateListeners()
}
animator = null
}
}
使用示例:
// 启动动画
val animator = PulseAnimator.applyTo(binding.logoImage)
// 停止动画
animator.stop()
方案2:ViewPropertyAnimator
简洁版实现(适合简单场景)
fun View.startPulse() {
val animDuration = 600L
animate()
.scaleX(1.2f)
.scaleY(1.2f)
.setDuration(animDuration)
.setInterpolator(AccelerateInterpolator())
.withEndAction {
animate()
.scaleX(1f)
.scaleY(1f)
.setDuration(animDuration)
.setInterpolator(DecelerateInterpolator())
.withEndAction {
if (isAttachedToWindow) startPulse()
}
}
}
// 停止需要调用View.clearAnimation()
三、关键参数解析
参数 说明 推荐值
duration 单次缩放周期时长 500-1000ms
repeatCount 重复次数 INFINITE(无限循环)
repeatMode 重复模式 REVERSE(往返动画)
interpolator 动画插值器 AccelerateDecelerate
pivotX/pivotY 缩放中心点 默认视图中心(无需设置)
四、最佳实践
- 生命周期管理
class MainActivity : AppCompatActivity() {
private var pulseAnimator: PulseAnimator? = null
override fun onStart() {
super.onStart()
pulseAnimator = PulseAnimator.applyTo(binding.logo)
}
override fun onStop() {
pulseAnimator?.stop()
super.onStop()
}
}
2. 性能优化技巧
对多个视图使用AnimatorSet统一管理
避免在RecyclerView项中直接使用无限动画
复杂场景考虑使用Lottie动画库
3. 高级扩展
带透明度的复合动画:
ObjectAnimator.ofPropertyValuesHolder(
view,
PropertyValuesHolder.ofFloat(View.SCALE_X, 1f, 1.2f),
PropertyValuesHolder.ofFloat(View.SCALE_Y, 1f, 1.2f),
PropertyValuesHolder.ofFloat(View.ALPHA, 1f, 0.8f)
).apply {
duration = 1000
repeatCount = INFINITE
repeatMode = REVERSE
}.start()