Android动画了解—RecyclerView Animator

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,重写几个关键的重要函数

函数名含义
animateRemoveitem 移除时的动画
animateAdditem 添加时的动画
animateMove移动时的动画 列表项位置移动时调用
animateChangeitem 更新时的动画
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动画不得不看的文章

谷歌API文档

深入理解 RecyclerView 系列之二:ItemAnimator

自定义RecyclerView ItemAnimator 上

自定义RecyclerView ItemAnimator 下


Android动画了解—转场/过渡(Transition) 动画<=上个章节 下个章节=> Android动画了解—其它动画

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值