1、属性动画
-
1.1、
ViewPropertyAnimator
/** * 最简单的动画,只能 平移,旋转,缩放等简单的 */ private fun animation() { view.animate() .translationX(dp2px(200F)) .translationY(dp2px(200F)) .scaleX(1.5F) .scaleY(1.5F) .rotation(300F) .setDuration(1_000) .setStartDelay(1_000) .start() }
-
1.2、
ObjectAnimator
ObjectAnimator.ofFloat(view, "mRadius", dp2px(0F), dp2px(100F)) .setDuration(1_000) .start() 这里 view 里面需要有一个 setMRadius 方法, 因为属性动画会一直调用该方法, 用来刷新属性 在 setXXX 方法里面需要手动调用 invalidate(), 因为只是改变了变量值, 并没有通知 view 刷新控件
-
1.3、
AnimatorSet
val topFlipAnimator = ObjectAnimator.ofFloat(view, "topFlip", 0F, -30F) .setDuration(1_000) val bottomFlipAnimator = ObjectAnimator.ofFloat(view, "bottomFlip", 0F, 30F) .setDuration(1_000) val flipRotationAnimator = ObjectAnimator.ofFloat(view, "flipRotation", 0F, 270F) .setDuration(1_000) AnimatorSet().apply { startDelay = 1_000 playSequentially(bottomFlipAnimator, flipRotationAnimator, topFlipAnimator) start() }
-
1.4、
PropertyValuesHolder
多个属性同时操作val bottomFlipHolder = PropertyValuesHolder.ofFloat("bottomFlip", 0F, 30F) val topFlipHolder = PropertyValuesHolder.ofFloat("topFlip", 0F, 30F) val flipRotationHolder = PropertyValuesHolder.ofFloat("flipRotation", 0F, 270F) ObjectAnimator.ofPropertyValuesHolder(view, bottomFlipHolder, topFlipHolder, flipRotationHolder) .apply { startDelay = 1_000 duration = 1_000 start() }
-
1.5、
Keyframe
同一个 view 的同一个属性 不同阶段val targetTranslationX = dp2px(200F) val keyframe1 = Keyframe.ofFloat(0F, 0F) val keyframe2 = Keyframe.ofFloat(0.1F, 1.5F * targetTranslationX) val keyframe3 = Keyframe.ofFloat(0.9F, 0.6F * targetTranslationX) val keyframe4 = Keyframe.ofFloat(1.0F, 1.0F * targetTranslationX) val translationXHolder = PropertyValuesHolder.ofKeyframe("translationX", keyframe1, keyframe2, keyframe3, keyframe4) ObjectAnimator.ofPropertyValuesHolder(view, translationXHolder) .apply { startDelay = 1_000 duration = 2_000 start() }
-
1.6、
Interpolator
速度模型view.animate() .translationX(dp2px(200F)) .setInterpolator(LinearInterpolator()) .setDuration(1_000) .setStartDelay(1_000) .start()
先加速后减速: 屏幕内两个点移动
加速: 从屏幕内移动到屏幕外
减速: 从屏幕外移动到屏幕内
- 1.7、
TypeEvaluator
估值器
估值器是指当动画进行到 10% 的时候, 值是多少,进行到 20% 的时候, 值是多少
基本数据类型有默认的估值器, 如果是别的对象比如 PointF() 就需要自己来写估值器
private fun typeEvaluator() {
val start = PointF(0F, 0F)
val des = PointF(dp2px(200F), dp2px(300F))
val animator = ObjectAnimator.ofObject(view, "mPointF", PointFEvaluator(), start, des)
animator.duration = 1_000
animator.startDelay = 1_000
animator.start()
}
class PointFEvaluator : TypeEvaluator<PointF> {
override fun evaluate(fraction: Float, startValue: PointF?, endValue: PointF?): PointF {
val x = (startValue?.x ?: 0F) + ((endValue?.x ?: 0F) - (startValue?.x ?: 0F)) * fraction
val y = (startValue?.y ?: 0F) + ((endValue?.y ?: 0F) - (startValue?.y ?: 0F)) * fraction
return PointF(x, y)
}
}
2、硬件加速
普通的绘制就是利用 CPU
来计算颜色值, 然后绘制, 而所谓的硬件加速是 GPU
来绘制
缺点: 兼容性, GPU
只能绘制简单的图形, 比如 矩形
, 圆
等
3、离屏缓冲
-
3.1、OffScreenBuffer
就是单独绘制 View 的一个区域, 为了让绘制过程不收到干扰, 或者在做动画的时候, 把某一块区域单独拿出来性能会更好 canvas.saveLayer() 保存状态, 而且还拉出来一个层 但是 saveLayer() 太重了, Google 不推荐这么做
-
3.2 setLayerType()
这个最好不要写在 onDraw() 里面, 因为会引起刷新
1、使用软件的方式离屏缓冲
setLayerType(LAYER_TYPE_SOFTWARE, null)
2、使用硬件的方式离屏缓冲
setLayerType(LAYER_TYPE_HARDWARE, null)
3、不用离屏缓冲
setLayerType(LAYER_TYPE_NONE, null)
- 3.3 关闭硬件加速
开启硬件加速:
关闭离屏缓冲之后会自动切换到硬件
setLayerType(LAYER_TYPE_NONE, null)
用 setLayerType(LAYER_TYPE_HARDWARE, null) 会开启硬件加速, 但是同时也会开启一个硬件的离屏缓冲
关闭硬件加速:
setLayerType(LAYER_TYPE_SOFTWARE, null)
- 3.4 硬件加速关于动画
只能用于简单的动画, 比如 translationX 等
view.animate()
.translationX(200F)
// 硬件加速
.withLayer()
.start()