一 补间动画的缺点
- 没有实质性的改变位置,只是视觉上改变了位置,点击事件依然在以前的位置
- 补间动画会触发同步屏障,导致一些有关IdleHandler的操作无法执行 , 比如Activity的onStop/onDestroy会延时10s执行
- 只能执行平移、缩放、旋转 和 透明度 几种系统固定的动画
二 属性动画
2.1 原理
在一定时间间隔内,通过反射不断对值进行改变、不断将该值赋给对象的属性(任意对象的任意属性),并且调用invalidate()进行重绘操作。
2.2 特点
- 真正的改变了View的位置,及点击事件生效
- 不会频繁的触发同步屏障,从而导致 IdleHandler 不会去执行
- 不局限于平移、缩放、旋转 和 透明度 几种系统固定的动画,自己也可以去设置属性
- API11引入
三 属性动画实现方式
3.1 ViewPropertyAnimator
优点
- 专门针对View对象动画而操作的类。
- 更简洁的链式调用设置多个属性动画
- 多个属性动画是一次同时变化,只执行一次UI刷新(也就是只调用一次invalidate,而n个ObjectAnimator就会进行n次属性变化,就有n次invalidate)
- View的animate()获取其实例对象的引用
val animate =
view.animate()
.translationX(50f.px)
.translationY(50f.px)
.scaleX(2f)
.scaleY(2f)
.rotation(45f)
.setDuration(1000)
animate.startDelay = 1000
animate.start()
3.2 ObjectAnimator
优点是除了可以更改系统的属性外,也可以更改咱们自定义的属性
3.2.1 实现上面的效果
val animatorTranslationY = ObjectAnimator.ofFloat(view, "translationY", 50f)
animatorTranslationY.duration = 2000
val animatorTranslationX: ObjectAnimator = ObjectAnimator.ofFloat(view, "translationX", 50f)
animatorTranslationX.duration = 2000
val animatorScaleX: ObjectAnimator = ObjectAnimator.ofFloat(view, "scaleX", 0.5f)
animatorScaleX.duration = 2000
val animatorScaleY: ObjectAnimator = ObjectAnimator.ofFloat(view, "scaleY", 0.5f)
animatorScaleY.duration = 2000
val animatorSet= AnimatorSet()
animatorSet.playTogether(animatorTranslationY,animatorTranslationX,animatorScaleX,animatorScaleY)
animatorSet.startDelay = 1000
animatorSet.start()
3.2.2 实现自定义属性的效果
定义出自定义类
class MyView(context: Context, attrs: AttributeSet) : View(context, attrs) {
private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.BLACK
}
// 自定义咱们改变的属性,这里简单的只是改变一下透明度
var myAlpha = 0f
set(value) {
field = value
// 调用 重绘制
invalidate()
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.withSave {
// 使用 myAlpha 进行透明度
paint.color = Color.argb(myAlpha, 0f, 0f, 0f)
canvas.drawRect(100f.px, 100f.px, 200f.px, 200f.px, paint)
}
}
}
使用,这样就改变了透明度
val animatorSize: ObjectAnimator = ObjectAnimator.ofFloat(view, "myAlpha", 1f)
animatorSize.duration = 2000
animatorSize.startDelay = 1000
animatorSize.start()
3.3 PropertyValuesHolder 和 Keyframe
PropertyValuesHolder 和 Keyframe配合,可以让动画精确到某一帧的效果
// keyframe 可以控制 精确到帧
val keyframe1 = Keyframe.ofFloat(0.0f, 0f)
val keyframe2 = Keyframe.ofFloat(0.25f, 1f)
val keyframe3 = Keyframe.ofFloat(0.5f, 2f)
val keyframe4 = Keyframe.ofFloat(0.75f, 1f)
val keyframe5 = Keyframe.ofFloat(1.0f, 2f)
val scalex = PropertyValuesHolder.ofKeyframe("scaleX", keyframe1,keyframe2,keyframe3,keyframe4,keyframe5)
val scaleY = PropertyValuesHolder.ofKeyframe("scaleY", keyframe1,keyframe2,keyframe3,keyframe4,keyframe5)
val animator: ObjectAnimator =
ObjectAnimator.ofPropertyValuesHolder(view, scalex, scaleY)
animator.duration = 3000
animator.startDelay = 1000
animator.start()
参考
属性动画-Property Animation之ViewPropertyAnimator 你应该知道的一切
Android 属性动画:这是一篇全面 & 详细的 属性动画 总结&攻略