item重排也要丝滑动画?三步开启SpannedGridLayoutManager的流畅过渡效果

📅 2026/8/26 20:00:39
item重排也要丝滑动画?三步开启SpannedGridLayoutManager的流畅过渡效果
item重排也要丝滑动画三步开启SpannedGridLayoutManager的流畅过渡效果【免费下载链接】SpannedGridLayoutManagerAndroid RecyclerView.LayoutManager that resizes and reorders views based on SpanSize项目地址: https://gitcode.com/gh_mirrors/sp/SpannedGridLayoutManagerSpannedGridLayoutManager 是一款开源 Android 库它继承自RecyclerView.LayoutManager能够根据每个 item 的 SpanSize行/列跨度自动缩放并重新排布网格中的所有视图——比如把某个 item 放大成 2×2其余 item 会自动流动填补缺口。但默认情况下重排往往是一下子硬切过去的。这篇指南将带你用3 步让重排过程拥有丝滑的平移、缩放过渡动画。为什么默认重排是生硬的RecyclerView 的 item 变化动画由 ItemAnimator 驱动而它的核心工作方式是通过稳定 ID 追踪同一个 item 在两次布局前后的位置然后计算位移、执行过渡。如果你的 Adapter 没有提供稳定 ID每次重排后所有 item 在动画器眼里都是新面孔于是直接瞬移——这正是很多开发者觉得重排不流畅的根本原因。所以开启动画的关键不在于布局管理器本身而在于补齐这三件事开启 Stable ID返回稳定的 item ID用正确的通知方式触发重新布局。三步开启丝滑过渡动画第一步在 Adapter 中开启 Stable ID只需一行代码声明本 Adapter 的 item 拥有稳定 IDsetHasStableIds(true)项目示例代码里就在初始化时完成了这一步可参考sample/src/main/java/com/arasthel/spannedgridlayoutmanager/sample/GridItemAdapter.kt。第二步重写 getItemId返回真正稳定的 IDoverride fun getItemId(position: Int): Long position.toLong()⚠️ 注意稳定的含义同一条数据在任何时候都必须返回同一个 ID。请避免使用随机 hashCode否则动画器会把同一个 item 误判为旧 item 消失 新 item 出现动画直接失效。示例中直接把 position 映射为 IDposition.toLong()简单可靠。第三步用 notifyDataSetChanged() 触发整局重排当 item 的 SpanSize 发生变化时例如某张卡片从 1×1 放大为 2×2请调用adapter.notifyDataSetChanged()布局管理器会执行一轮完整重排动画器对比出每个 ID 的新旧帧位置平移与缩放过渡便自动开始。完整示例点击卡片放大全网格流动下面是一个典型用法与示例 App 一致4 列网格点亮的 item 占 2×2其余占 1×1点击后触发重排动画。val layout SpannedGridLayoutManager(Orientation.VERTICAL, spans 4) layout.spanSizeLookup SpannedGridLayoutManager.SpanSizeLookup { pos - if (adapter.clickedItems[pos]) SpanSize(2, 2) else SpanSize(1, 1) } recyclerView.layoutManager layout recyclerView.adapter adapter完整可运行代码见sample/src/main/java/com/arasthel/spannedgridlayoutmanager/sample/MainActivity.kt和sample/src/main/java/com/arasthel/spannedgridlayoutmanager/sample/GridItemAdapter.kt。动画背后的排布算法空闲矩形拆分 为什么 item 能填补缺口、甚至无视原有顺序重新排布核心在 SpannedGridLayoutManager.kt 中的RectsHelper初始时整个网格是1 个空闲矩形每放入一个 item就把被占用的矩形沿左、右、上、下切分成最多 4 个子矩形如右图所示下一个 item 总是落入第一个能容纳它的空闲位置——这就是先补近处空洞的视觉效果来源也是丝滑动画能逐帧追踪每个 item 位移的几何基础。该算法的详细推导可以查阅项目根目录的free_space_algorithm.pdf。常见坑与小贴士 ✅SpanSize 越界会抛异常跨度必须落在1 ~ spans之间否则会抛出InvalidSpanSizeException定义于 InvalidSpanSizeException.kt。滚动位置恢复默认关闭因为重排可能大幅改变 item 顺序为避免滚动位置错乱LayoutManager 默认不恢复滚动位置。若你确信顺序变化不大可设置itemOrderIsStable true重新开启。SpanSize 计算很复杂时给spanSizeLookup打开缓存usesCache true数据变化后调用invalidateCache()刷新避免重复计算。总结让 SpannedGridLayoutManager 的重排动画活起来本质上只有三步开启 Stable ID → 返回稳定 ID → notifyDataSetChanged 触发重排。三步全部就位后放大、缩小、换位都会获得连贯的过渡效果——这正是自动填满空隙类网格布局想要达到的理想体验。【免费下载链接】SpannedGridLayoutManagerAndroid RecyclerView.LayoutManager that resizes and reorders views based on SpanSize项目地址: https://gitcode.com/gh_mirrors/sp/SpannedGridLayoutManager创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考