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

2021-01-03 21:15:44 +08:00
 john6lq

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

  1. 页面初始化的时候不执行动画,后续滑动列表显示 item 的时候相应 item 执行动画。
  2. notifyDatasetChanges 的时候不执行动画
5083 次点击
所在节点    Android
13 条回复
chenjiajia9411
2021-01-04 09:42:51 +08:00
john6lq
2021-01-04 11:01:41 +08:00
@chenjiajia9411 这个看过了,`itemAnimator`是`item`发生改变时才会触发,比如`add`、`remove`、`move`、`change`这些。我看了几天源码安卓上没有合适的方法做这个需求。

但是,如果摸透了`RecyclerView`,不知道可不可以魔改 `itemAnimator`,添加一种状态来实现。
chenjiajia9411
2021-01-04 11:23:46 +08:00
@john6lq #2 ItemAnimator 本来就不会响应 notifyDatasetChanged,因为它以单个 Item 为基本单位,在调用 notifyDatasetChanged 的时候默认都是对原有数据做了非常大的改动,无法计算有多少 Item 需要有动画,所以它会直接刷新整个 RecyclerView,ItemAnimator 根本不会被执行。
关于你的第一个需求,可以先调用你的 RecyclerView 的 LayoutManager 的 findLastCompletelyVisibleItemPosition()或者 findLastVisibleItemPosition()方法获取界面上最后一个可见的 Item 的位置,然后直接调用 ItemAnimator 的 dispatchAnimationFinished(ViewHolder)并传入不需要动画的 ViewHolder 来取消动画。
hstan
2021-01-04 14:43:35 +08:00
MotionLayout 看看能不能满足你的需求
pdog18
2021-01-04 23:27:53 +08:00
如果你 notifyDatasetChanged 时触发了 itemAnimator 产生动画,那么说明你在 Adapter 通过 getItem 实现了 stableId
john6lq
2021-01-05 00:10:13 +08:00
@chenjiajia9411 item 进入时让这个 item 的 view 执行动画,你确定 ItemAnimator 可以做到?这个类是用于 item 数据发生改变时执行动画的。
chenjiajia9411
2021-01-05 09:38:26 +08:00
@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
2021-01-05 11:19:50 +08:00
@chenjiajia9411 你误会了,需求上“item 显示时”不是新增一条数据,而是这个 item 从不可见变为可见。“itemAnimator”只是在数据发生改变时提供动画。要不我提什么“onBindViewHolder”?
q197
2021-01-05 11:22:12 +08:00
brvah 库
chenjiajia9411
2021-01-05 11:30:16 +08:00
@john6lq #8 我误会了,从不可见变为可见这种状态改变可以用 notifyItemChanged,然后在 SimpleItemAnimator 的 animateChange 里做你需要的动画。
john6lq
2021-01-05 12:39:44 +08:00
@q197 看了一下,这个库的动画是在 onViewAttachedToWindow 内执行的,这里可以看见
https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/library/src/main/java/com/chad/library/adapter/base/BaseQuickAdapter.kt

这和在 onBindViewHolder 内执行没啥区别。另外这库其实就是个辅助类,花里胡哨的,kotlin 后用 RecyclerView 其实没必要搞这么复杂了。
dengxuejiu
344 天前
遇到了同样的问题,请问有解决方案吗,我的需求是实现 iOS 的通知中心的滑动效果
john6lq
344 天前
@dengxuejiu iOS 15 用 [[Cask 3]],这个插件支持自定义列表动画

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/741287

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX