[Android]自定义RecyclerView中View的动画

参考默认动画类DefaultItemAnimator

官方有一个默认Item动画类DafaultItemAnimator,其中 DefaultItemAnimator 继承了SimpleItemAnimator 继承了 RecyclerView.ItemAnimator

  1. SimpleItemAnimator 它是一个包装类,用来判断当前的ViewHolder到底是执行移动、移除、添加或者改变等行为。
  2. DefaultItemAnimator 是执行具体动画类,它负责将viewHolder初始化、保存需要执行动画的ViveHolder以及动画信息、执行具体的动画。 我们自定义ItemAnimtor 也是仿照这个来的。
  3. 其中DefaultItemAnimator中 animate + 动作 为名的的方法(比如animateAdd())做的事情有:计算动画信息,保存动画信息,初始化view的状态,且可以控制该VIewHolder是否执行该次动画,如果返回值为false那么那么不会执行该ViewHolder的改次动画。
  4. DefaultItemAnimator中animate + 动作 + Impl 为名的方法,做的动作是执行具体的动画动作。
  5. runPendingAnimations是最终执行具体动画的方法

产生动画的流程

RecyclerView 的 onLayout 方法主要调用了 dispatchLayout 方法,dispatchLayout 中保障了 dispatchLayoutStep1、2、3 三个方法的执行。

dispatchLayoutStep1

  1. 首先将当前屏幕中的 items 信息保存;(生成 ItemHolderInfo 赋值给 InfoRecord 的 preInfo 并且对其 flags 添加 FLAG_PRE ,再将 InfoRecord 添加到 ViewInfoStore 的 mLayoutHolderMap 中
  2. 进行预布局;(调用 LayoutManager 的 onLayoutChildren)
  3. 预布局完成后和第 1 步中保存的信息对比,将新出现的 item 信息保存;(和第 1 步中不同的是 flags 设置的是 FLAG_APPEAR)

dispatchLayoutStep2

  1. 将预布局 boolean 值改为 flase;
  2. 进行真正布局;(调用 LayoutManager 的 onLayoutChildren)

dispatchLayoutStep3

  1. 将真正布局后屏幕上的 items 信息保存;(与 dispatchLayoutStep1 不同的是赋值给 InfoRecord 的 postInfo 并且 flags 添加 FLAG_POST)
  2. 执行动画,调用 ViewInfoStore.process();
  3. 布局完成回调,onLayoutCompleted;

仿照 DefaultItemAnimator 搭建据图框架Base框架

public class BaseItemAnimator extends SimpleItemAnimator {
    //业务控制是否执行该viewHolder的动画  比如通讯录列表,判断只有联
    //系人的ViewHolder执行动画,如果是分组头部ViewHolder则不执行动画
    @Override
    public boolean animateRemove(RecyclerView.ViewHolder holder) {
        // 计算 holder的动画参数 如:x偏移量 y轴偏移量 透明度等等
        // 保存 viewHolder 以及 动画参数
        //  业务控制是否执行该viewHolder的动画  
        //      比如通讯录列表,判断只有联系人的ViewHolder执行动画,
        //      如果是分组头部ViewHolder则不执行动画
        return false;
    }

    @Override
    public boolean animateAdd(RecyclerView.ViewHolder holder) {
        // 计算 holder的动画参数 如:x偏移量 y轴偏移量 透明度等等
        // 保存 viewHolder 以及 动画参数
        //  业务控制是否执行该viewHolder的动画  
        return false;
    }


    //用于控制添加,移动更新时,其它Item的动画执行
    @Override
    public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
        // 计算 holder的动画参数 如:x偏移量 y轴偏移量 透明度等等
        // 保存 viewHolder 以及 动画参数
        //  业务控制是否执行该viewHolder的动画  
        return false;
    }

    //Item更新回调
    @Override
    public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop) {
        // 计算 holder的动画参数 如:x偏移量 y轴偏移量 透明度等等
        // 保存 viewHolder 以及 动画参数
        //  业务控制是否执行该viewHolder的动画  
        return false;
    }

    //真正控制执行动画的地方
    //关键方法,参考DafaultItemAnimator的执行,在具体的子方法下面去修改和重载
    @Override
    public void runPendingAnimations() {
            // 根据保存的 viewHolder 以及 animInfo   执行动画
    }
	...
}

给 RecyclerView 设置动画调用 setItemAnimator 方法,将自定义的Animator设置给RecyclerView即可。

参考文章:

https://juejin.cn/post/7169857225949708301
https://www.jianshu.com/p/7171ea362513

源码:

MultiTypeAdapter

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值