Recyclerview animation
Began when RecyclerView animation, when we UI 2.0 ~ 3.0, and many places in need of such RecyclerView interface 初始化
, 添加
, 移除
, 更新
animation style data.
Look at some small demos initialized by RecycelrView Adapter
除了这种方式进行初始化,我们还可以用前面所讲的过渡动画来进行
Transition explode = new Explode();
explode.setDuration(1000);
TransitionManager.beginDelayedTransition(recyclerView, explode);
if (recyclerView.getAdapter() != null) {
recyclerView.setAdapter(null);
} else {
recyclerView.setAdapter(mColorsAdapter);
}
Look at the addition, removal, and update of RecyclerView Item
If Item animation is not set, RecyclerView uses it by default DefaultItemAnimator(继承的 SimpleItemAnimator)
.
If you want to achieve some of the above effects ( Demo address ), we need to customize our own Item Animator, just inherit SimpleItemAnimator and rewrite several key important functions
Function name | meaning |
---|---|
animateRemove |
Animation when item is removed |
animateAdd |
Animation when item is added |
animateMove |
Animation when moving, called when the position of the list item moves |
animateChange |
Animation when item is updated |
runPendingAnimations |
Really control where the animation is performed |
endAnimation |
Stop the animation of an Item |
endAnimations |
Stop all animations |
isRunning |
Returns whether there is an animation that needs to be executed |
Related functions that will be called in the custom Item Animator:
Function name | meaning |
---|---|
dispatch(Add/Remove/Move/Change)Starting |
Called when the animation starts, such as Add dispatchAddStarting |
dispatch(Add/Remove/Move/Change)Finished |
Called when the animation ends, such as Add dispatchAddFinished |
dispatchAnimationsFinished |
Called at the end of all animations |
Several functions that trigger Item animation
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
First customize a small DEMO that adds the animation effect of Item View
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官方实现兼容的一个帮助类,具体可以查找网上相关资料
Official information
You can try ( notifyItemInserted(position)
) whether there is an animation effect, it must have no effect, because it has not been initialized to its initial appearance! ! !
Let’s change the code...
... ...
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);
}
... ...
After code modification, adding ItemView can achieve the following effects.
You will find that the above RecyclerView ItemView of 添加
animation, okay, that is, when new, the other following ItemView movement is very stiff, so here leads to the animateMove
function.
Function name | parameter | Parameter meaning |
---|---|---|
animateMove | (final ViewHolder holder, int fromX, int fromY, int toX, int toY) | Called when the list item position moves, the moved ViewHolder; fromX starting x, y value; toX target x, y value |
@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();
... ...
}
Adding the animation effect of Item View throughout, that's it! ! !
Of course, in the project, it is certainly not that simple. Here is just a simple example to illustrate the importance of the next few functions.
If it is used in a project, you only need to inherit this BaseitemAnimator
and write some effects you want, but most of the animation effects have been implemented here.
Those who need to use the above effects can download by themselves, code base address
5.x references
RecyclerView animations
RecyclerView anim video
Articles you have to read to master RecyclerView animation
In-depth understanding of RecyclerView series two: ItemAnimator
Customize RecyclerView ItemAnimator on
Customize RecyclerView ItemAnimator
Android Animation Understanding—Transition/Transition Animation <=Previous Chapter Next Chapter=> Android Animation Understanding—Other Animations