通过本篇文章,你将会了解
- 安卓属性动画的基本架构
- 插值器和估值器在动画中的作用
- 手撸属性动画
设想一下,如果你是google的工程师,让你去设计一个属性动画,你该如何设计?在设计属性动画时我们应该要考虑哪些问题?
- 生成动画的api调用约简单越好
- 一个View可以有多个动画,但同时只能有一个在运行
- 动画的执行不能依赖自身的for循环
- 如何让动画动起来
我们先来看下属性动画的种类
- 平移动画
- 透明度动画
- 缩放动画
- 旋转动画
- 帧动画
属性动画的使用
ObjectAnimator animator = ObjectAnimator.ofFloat(view,"scale",1f,2f,3f);
animator.setInterpolator(new LinearInterpolator());
animator.setDuration(500);
animator.start()
动画的本质
动画实际上是改变View在某一时间点上的样式属性,比如在0.1s的时候View的x坐标为50px,在0.2s的时候View的x坐标变为150px,在0.3s的时候View的x坐标变为250px,肉眼看就会感觉View在向右移动。
实际上是通过一个线程每隔一段时间通过调用view.setX(index++)来改变属性值产生动画效果。
动画实际上是一个复杂的流程,需要考虑的因素比较多,在开发者层面不建议直接调用view.setX()来实现动画。
动画架构分析
根据上面的架构图,我们将动画任务拆成若干个关键帧,每个关键帧在不同的时间点执行自己的动画,最终将整个动画完成,但每两个关键帧之间是有时间间隔的,我们要实现一个补帧的操作来过渡两个关键帧动画,使动画看起来衔接平滑自然。
这里可能大家会有一个疑问:为什么要将动画分解成不同的关键帧?原因是动画完成是需要时间开销的。如果不给出关键帧动画,动画的过程将无法控制,而且在不同的时间点,控件的状态也不一样。
代码设计架构图
撸代码
1、首先我们来模拟VSync信号,每隔16ms发送一个信号去遍历animationFrameCallbackList执行动画Callback,定义一个VSyncManager类来模拟
public class VSyncManager {
private List<AnimationFrameCallback> list = new ArrayList<>();
public static VSyncManager getInstance() {
return Holder.instance;
}
private VSyncManager() {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(16);
} catch (Exception e) {
e.printStackTrace();
}