Recyclerview animation
什么时候开始的 RecyclerView animation,在我们UI 2.0~3.0的时候,很多地方都需要这种 RecyclerView 界面 初始化
,添加
,移除
,更新
数据的 动画效果样式.
看几个RecycelrView Adapter 初始化的小DEMO
除了这种方式进行初始化,我们还可以用前面所讲的过渡动画来进行
Transition explode = new Explode();
explode.setDuration(1000);
TransitionManager.beginDelayedTransition(recyclerView, explode);
if (recyclerView.getAdapter() != null) {
recyclerView.setAdapter(null);
} else {
recyclerView.setAdapter(mColorsAdapter);
}
再看看 RecyclerView Item 添加,移除,更新的的小栗子
如果没有设置 Item animation,RecyclerView 默认使用的就是 DefaultItemAnimator(继承的 SimpleItemAnimator)
。
如果想实现上面的一些效果(Demo地址),我们就需要 自定义自己的 Item Animator ,只需要继承 SimpleItemAnimator,重写几个关键的重要函数
函数名 | 含义 |
---|---|
animateRemove | item 移除时的动画 |
animateAdd | item 添加时的动画 |
animateMove | 移动时的动画 列表项位置移动时调用 |
animateChange | item 更新时的动画 |
runPendingAnimations | 真正控制执行动画的地方 |
endAnimation | 停止某个Item的动画 |
endAnimations | 停止所有动画 |
isRunning | 返回当前是否有动画需要执行 |
在自定义Item Animator 中会调用到的相关函数:
函数名 | 含义 |
---|---|
dispatch(Add/Remove/Move/Change)Starting | 动画开始时调用,比如Add dispatchAddStarting |
dispatch(Add/Remove/Move/Change)Finished | 动画结束时调用,比如Add dispatchAddFinished |
dispatchAnimationsFinished | 所有动画结束时调用 |
引发 Item 动画的几个函数
Adapter.notifyItemInserted(int position) // 触发 Add Item Animator
Adapter.notifyItemRemoved(int position) // 触发 Remove Item Animator
Adapter.notifyItemChanged(int position) // 触发 Change Item Animator
Adapter.notifyItemMoved(int fromPosition, int toPosition) // 触发 MoveItem Animator
先来自定义的一个添加Item View的动画效果的小DEMO
public class CumtomAnimator extends SimpleItemAnimator {
// 保存 需要做 add 动画效果的 itemView 的数组
private ArrayList<RecyclerView.ViewHolder> mPendingAdditions = new ArrayList<>();
@Override
public boolean animateAdd(RecyclerView.ViewHolder holder) {
// 添加对应的数据,主要用于 runPendingAnimations 执行动画效果
mPendingAdditions.add(holder);
}
@Override
public void runPendingAnimations() {
for (RecyclerView.ViewHolder holder : mPendingAdditions) {
ViewCompat.animate(holder.itemView)
.scaleX(1.0f)
.scaleY(1.0f)
.setDuration(getAddDuration())
.start();
}
// 记得要清理掉,不然其它动画执行后,要被影响,而且也影响 isRunning 的判断
mPendingAdditions.clear();
}
@Override
public boolean isRunning() {
return !mPendingAdditions.isEmpty()
|| ... ...
}
... ...
}
ViewCompat:android官方实现兼容的一个帮助类,具体可以查找网上相关资料
官方资料
可以试试(notifyItemInserted(position)
)有没有动画效果,肯定是没有效果的,因为没有去初始化它 起始的样子!!!
来改改代码… …
... ...
public boolean animateAdd(RecyclerView.ViewHolder holder) {
// 初始化动画状态
// 将 ItemView 设置为 ScaleX,ScaleY 都为0
// 那么执行动画效果的时候,就是从 中间位置 然后 放大 0.0f -> 1.0f
View itemView = holder.itemView;
ViewCompat.setPivotY(itemView, itemView.getMeasuredHeight() / 2);
ViewCompat.setPivotX(itemView, itemView.getMeasuredWidth() / 2);
ViewCompat.setScaleX(itemView, 0);
ViewCompat.setScaleY(itemView, 0);
// 添加对应的数据,主要用于 runPendingAnimations
mPendingAdditions.add(holder);
}
... ...
代码修改后,添加 ItemView 就能达到下面的效果。
你会发现,上面的 RecyclerView ItemView的添加
动画效果,还行,就是新增的时候,下面的其它的ItemView 移动的很生硬,所以这里就引出了 animateMove
函数。
函数名 | 参数 | 参数含义 |
---|---|---|
animateMove | (final ViewHolder holder, int fromX, int fromY, int toX, int toY) | 列表项位置移动时调用,移动的ViewHolder;fromX 起始x,y值;toX 目标x,y值 |
@Override
public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
// 设置它的初始位置.
final View view = holder.itemView;
// 目标的位置 减去 起始位置(原来的位置),得到需要位移的距离
int deltaX = toX - fromX;
int deltaY = toY - fromY;
// 设置后,相当于从 新的位置 回到了 原来的位置上.
if (deltaX != 0) {
ViewCompat.setTranslationX(view, -deltaX);
}
if (deltaY != 0) {
ViewCompat.setTranslationY(view, -deltaY);
}
mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY));
}
@Override
public void runPendingAnimations() {
... ...
// 最后从原来的位置 做动画,回到新的位置上,就完整了移动的动画效果.
for (MoveInfo moveInfo : mPendingMoves) {
ViewCompat.animate(moveInfo.holder.itemView)
.translationX(0)
.translationY(0)
.setDuration(getMoveDuration())
.start();
}
mPendingMoves.clear();
... ...
}
整个添加Item View的动画效果,就这样完成啦!!!
当然在项目,肯定没有那么简单,这里只是简单的举个小栗子,给大家说明下几个函数的重要性.
如果是项目中使用,只需要继承这个 BaseitemAnimator
,写一些自己想要的效果就OK,不过这里已经实现了大多数的动画效果。
需要使用以上效果的小伙伴,自行下载,代码库地址
5.x 参考资料
RecyclerView animations 国外大神文章
RecyclerView anim视频
深入理解 RecyclerView 系列之二:ItemAnimator
自定义RecyclerView ItemAnimator 上
自定义RecyclerView ItemAnimator 下
Android动画了解—转场/过渡(Transition) 动画<=上个章节 下个章节=> Android动画了解—其它动画