本文要解决的问题:
1. Recyclerview 动画的实现原理是什么?
2. 处理的主要流程大概是怎样的?
我们抛开代码,想一下,RecyclerView中的view动画有几种?
添加一个view:添加的View 显示出来,它下面的所有view向下移动一格距离
删除一个view:删除的View 渐隐掉,它下面的所有view向上移动一格距离
上下滑动:所有子view上下滑动
移动:…
归纳起来,最终实现动画的时候,无外乎会执行几个操作:
添加或删除View的 透明度动画 0->1 或 1->0
子view的y轴坐标,由动画前的位置,滑动到 动画后的位置(我们暂时只讨论常见的竖向布局)
所以,看似复杂的RecyclerView动画处理,经过分解后,其实就是一个view的简单动画,没有任何新奇的玩意或算法。
所有需要做的就是,记录下动画执行前view的状态(透明度,y坐标),以及计算出动画的目的地(透明度,y坐标),然后执行动画,仅此而已,这就是RecyclerView动画实现的核心原理。
经过上面的分析,其实我们的重点变成了,view数据的组织与记录(动画前),view的数据的计算(动画后),心里要有这个数。
然后,我们大概看一下,整个流程:
核心接口:RecyclerView.ItemAnimator
核心实现类:DefaultItemAnimator
核心实现方法:DefaultItemAnimator.runPendingAnimations()
调用栈如下:
DefaultItemAnimator.runPendingAnimations() — 核心方法
|
RecyclerView.mItemAnimatorRunner
|
RecyclerView.postAnimationRunner()
|
ViewInfoStore.ProcessCallback
|
ViewInfoStore.process(ProcessCallback callback)
|
RecyclerView.dispatchLayoutStep3() 触发动画的根
=== RecyclerView.java
private void dispatchLayoutStep3() {
......
// Step 4: Process view info lists and trigger animations
mViewInfoStore.process(mViewInfoProcessCallback);
}
核心类:ViewInfoStore
核心数据结构:mLayoutHolderMap
final SimpleArrayMap<RecyclerView.ViewHolder, InfoRecord> mLayoutHolderMap =
new SimpleArrayMap<>();
ViewInfoStore这个类,抽象了所有的子View的(为了运行动画的)跟踪信息。
看下mLayoutHolderMap,ViewHolder就是子view,映射了一个InfoRecord
static class InfoRecord {
@Nullable
RecyclerView.ItemAnimator.ItemHolderInfo preInfo;
@Nullable
RecyclerView.ItemAnimator.ItemHolderInfo postInfo;
一目了然,preInfo是动画执行前的信息,postInfo是动画执行后的信息。
public static class ItemHolderInfo {
public int left;
public int top;
public int right;
public int bottom;
public int changeFlags;
ItemHolderInfo 记录了View的坐标与flag。
推断逻辑:
也就是说在2.1最终执行动画前,ViewInfoStore中的数据应该是已经准备好的。
核心类:ViewInfoStore
核心方法:addToPreLayout()
入口:RecyclerView.dispatchLayoutStep1()
final ItemHolderInfo animationInfo = mItemAnimator
.recordPreLayoutInformation(mState, holder,
ItemAnimator.buildAdapterChangeFlagsForAnimations(holder),
holder.getUnmodifiedPayloads());
mViewInfoStore.addToPreLayout(holder, animationInfo);
核心类:ViewInfoStore
核心方法:addToPostLayout()
入口:RecyclerView.dispatchLayoutStep3()
final ItemHolderInfo animationInfo = mItemAnimator
.recordPostLayoutInformation(mState, holder);
......
mViewInfoStore.addToPostLayout(holder, animationInfo);
以上,就是本篇的主要内容了。
以后有时间的话,补一下细节流程,再更新吧。
/// 三、源码分析 - 细节流程分析