john6lq
V2EX  ›  Android

RecyclerView 有办法优雅实现列表动画吗?

  •  
  •   john6lq · Jan 3, 2021 via iPhone · 13926 views
    This topic created in 1963 days ago, the information mentioned may be changed or developed.

    目前是在 onBindViewHolder 中做的。 目标需求是

    1. 页面初始化的时候不执行动画,后续滑动列表显示 item 的时候相应 item 执行动画。
    2. notifyDatasetChanges 的时候不执行动画
    13 replies    2023-05-20 11:05:14 +08:00
    john6lq
        2
    john6lq  
    OP
       Jan 4, 2021   ❤️ 1
    @chenjiajia9411 这个看过了,`itemAnimator`是`item`发生改变时才会触发,比如`add`、`remove`、`move`、`change`这些。我看了几天源码安卓上没有合适的方法做这个需求。

    但是,如果摸透了`RecyclerView`,不知道可不可以魔改 `itemAnimator`,添加一种状态来实现。
    chenjiajia9411
        3
    chenjiajia9411  
       Jan 4, 2021
    @john6lq #2 ItemAnimator 本来就不会响应 notifyDatasetChanged,因为它以单个 Item 为基本单位,在调用 notifyDatasetChanged 的时候默认都是对原有数据做了非常大的改动,无法计算有多少 Item 需要有动画,所以它会直接刷新整个 RecyclerView,ItemAnimator 根本不会被执行。
    关于你的第一个需求,可以先调用你的 RecyclerView 的 LayoutManager 的 findLastCompletelyVisibleItemPosition()或者 findLastVisibleItemPosition()方法获取界面上最后一个可见的 Item 的位置,然后直接调用 ItemAnimator 的 dispatchAnimationFinished(ViewHolder)并传入不需要动画的 ViewHolder 来取消动画。
    hstan
        4
    hstan  
       Jan 4, 2021
    MotionLayout 看看能不能满足你的需求
    pdog18
        5
    pdog18  
       Jan 4, 2021
    如果你 notifyDatasetChanged 时触发了 itemAnimator 产生动画,那么说明你在 Adapter 通过 getItem 实现了 stableId
    john6lq
        6
    john6lq  
    OP
       Jan 5, 2021 via iPhone
    @chenjiajia9411 item 进入时让这个 item 的 view 执行动画,你确定 ItemAnimator 可以做到?这个类是用于 item 数据发生改变时执行动画的。
    chenjiajia9411
        7
    chenjiajia9411  
       Jan 5, 2021
    @john6lq #6 你不信的话可以手动调用 notifyItemInserted 看看有没有效果啊,RecyclerView 默认有一个 DefaultItemAnimator ( https://developer.android.com/reference/androidx/recyclerview/widget/DefaultItemAnimator )所以能直接看到效果的。
    注意一定要是真正的向原始 list 插入一个 item 而不是把 list 整个替换之后再调用,使用 SortedList ( https://developer.android.com/reference/androidx/recyclerview/widget/SortedList )或者 AsyncListDiffer ( https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer )可能是更好的选择。
    john6lq
        8
    john6lq  
    OP
       Jan 5, 2021
    @chenjiajia9411 你误会了,需求上“item 显示时”不是新增一条数据,而是这个 item 从不可见变为可见。“itemAnimator”只是在数据发生改变时提供动画。要不我提什么“onBindViewHolder”?
    q197
        9
    q197  
       Jan 5, 2021
    brvah 库
    chenjiajia9411
        10
    chenjiajia9411  
       Jan 5, 2021
    @john6lq #8 我误会了,从不可见变为可见这种状态改变可以用 notifyItemChanged,然后在 SimpleItemAnimator 的 animateChange 里做你需要的动画。
    john6lq
        11
    john6lq  
    OP
       Jan 5, 2021
    @q197 看了一下,这个库的动画是在 onViewAttachedToWindow 内执行的,这里可以看见
    https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/library/src/main/java/com/chad/library/adapter/base/BaseQuickAdapter.kt

    这和在 onBindViewHolder 内执行没啥区别。另外这库其实就是个辅助类,花里胡哨的,kotlin 后用 RecyclerView 其实没必要搞这么复杂了。
    dengxuejiu
        12
    dengxuejiu  
       May 19, 2023
    遇到了同样的问题,请问有解决方案吗,我的需求是实现 iOS 的通知中心的滑动效果
    john6lq
        13
    john6lq  
    OP
       May 20, 2023
    @dengxuejiu iOS 15 用 [[Cask 3]],这个插件支持自定义列表动画
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1030 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 46ms · UTC 19:02 · PVG 03:02 · LAX 12:02 · JFK 15:02
    ♥ Do have faith in what you're doing.