如何实现上下抖动动画效果
方案1
我们可以直接通过一个属性动画直接实现,但是实现效果不好
// 要实现抖动的view
var view = findViewById<View>(R.id.anim_layout)
var downAnim = ObjectAnimator.ofFloat(view, "translationY", 0F, 100F, -100F)
downAnim.repeatMode = ValueAnimator.REVERSE
downAnim.repeatCount = ValueAnimator.INFINITE
downAnim.interpolator = LinearInterpolator()
downAnim.duration = 1000
downAnim.start()
效果图
我们通过反向循环的方法实现,可以看到动画明显不连续,效果不是很好,放弃方案1,我们想到还可以通过AnimatorSet来实现,于是方案2
方案2
// 要实现抖动的view
var view = findViewById<View>(R.id.anim_layout)
var set = AnimatorSet()
// 向下动画
var downAnim = ObjectAnimator.ofFloat(view, "translationY", 0F, 100F, 0F)
// 向上动画
var upAnim = ObjectAnimator.ofFloat(view, "translationY", 0F, -100F, 0F)
upAnim.repeatMode = ValueAnimator.REVERSE
set.duration = 1000
// 顺序执行动画
set.playSequentially(downAnim, upAnim)
set.start()
效果图
我们先执行向下动画然后恢复到原位置,然后再执行向上动画再恢复原位,效果明显好很多,但是向上动画,和向下动画切换处能看出停顿,于是出现了终极方案
终极方案
我们还是通过两个动画来实现,不过我们不再通过set进行统一管理,我们通过相互监听得方式来实现循环,即向下动画执行结束,在onAnimationEnd中启动向上动画,同理设置向上动画。
var view = findViewById<View>(R.id.anim_layout)
var downAnim = ObjectAnimator.ofFloat(view, "translationY", 0F, 100F, 0F)
var upAnim = ObjectAnimator.ofFloat(view, "translationY", 0F, -100F, 0F)
downAnim.duration = 1000
upAnim.duration = 1000
downAnim.interpolator = LinearInterpolator()
upAnim.interpolator = LinearInterpolator()
downAnim.addListener(object :AnimatorListenerAdapter(){
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
// 向下动画结束,启动向上动画
upAnim.start()
}
})
upAnim.addListener(object :AnimatorListenerAdapter(){
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
// 向上动画结束,启动向下动画
downAnim.start()
}
})
// 先启动一次
downAnim.start()
效果图
虽然循环依赖很是恶心,但是效果是最好的!有大佬有其他方案欢迎交流啊。