如何用函数组合动态构建 RecyclerView:Android-Extensions ComposedAdapter 完全解析
【免费下载链接】Android-ExtensionsAn Android library with modules to quickly bootstrap an Android application.项目地址: https://gitcode.com/gh_mirrors/an/Android-Extensions
在 Android 开发中,ComposedAdapter是 Android-Extensions 库里最被低估的组件之一:它让你不继承任何类,只用几个函数就能动态构建一个 RecyclerView 适配器。对于新手来说,这意味着告别冗长的onCreateViewHolder、onBindViewHolder样板代码,用 Kotlin 风格更简洁地搞定列表。
传统 Adapter 写法为什么让人头疼?
按官方推荐,你通常要这样做三件事:
- 继承
RecyclerView.Adapter,重写创建、绑定、计数等方法; - 为每种单元格单独定义一个
ViewHolder子类; - 想监听复用、附加、回收等回调时,再重写更多方法。
数据一变,还得手动notifyDataSetChanged(),闪烁、卡顿风险全靠自己小心。
Android-Extensions 的 RecyclerView 模块给出的思路是:别再继承 Adapter 了,把它“组合”出来——核心类就是ComposedAdapter(源码位置:recyclerview/src/main/java/com/tunjid/androidx/recyclerview/ComposedAdapter.kt)。
两个核心函数:创建 + 绑定
调用入口是adapterOf()函数,必填参数只有三个:
itemsSource:() -> List<ItemT>,一个“取数据”的函数,每次查询列表时都会调用,天然支持数据源随时变化;viewHolderCreator:(parent, viewType) -> ViewHolder,负责创建单元格视图;viewHolderBinder:(holder, item, position) -> Unit,负责把数据绑定到单元格上。
下面这段就是项目里真实的用法(app/src/main/java/com/tunjid/androidx/tablists/doggo/DoggoListFragment.kt),整个狗狗网格列表就是这样搭起来的:
adapter = adapterOf( itemsSource = Doggo.Companion::doggos, viewHolderCreator = { parent, _ -> parent.viewHolderFrom(ViewholderDoggoListBinding::inflate) }, viewHolderBinder = { holder, doggo, _ -> holder.doggoBinder?.bind(doggo) }, itemIdFunction = { it.hashCode().toLong() } )注意viewHolderFrom是配套的BindingViewHolder能力(recyclerview/src/main/java/com/tunjid/androidx/recyclerview/viewbinding/BindingViewHolder.kt):直接由 ViewBinding 类生成 ViewHolder,连 ViewHolder 子类都不用写。
可选参数速查:动态列表的全部控制点
adapterOf()还有 9 个可选参数,按需传入即可,不传就回落到默认行为:
| 参数 | 作用 | 适合场景 |
|---|---|---|
viewHolderPartialBinder | 带 payloads 的局部更新绑定 | 只刷新某一行、避免整页重绘 |
viewTypeFunction | 根据数据项决定视图类型 | 混合多种样式的列表 |
itemIdFunction | 提供稳定 ID(自动开启 stableIds) | 共享元素转场、按 ID 查找视图 |
onViewHolderAttached / Detached | 单元格进入/离开窗口回调 | 播放暂停动画、统计曝光 |
onViewHolderRecycled / RecycleFailed | 回收成功与回收失败回调 | 排查“无法回收”警告 |
onAttachedToRecyclerView / onDetachedFromRecyclerView | Adapter 挂载/卸载回调 | 附加 ItemDecoration、监听器 |
这些回调覆盖了标准 Adapter 的全部生命周期钩子,等于把“需要重写的每一个方法”都变成了“可选的函数参数”。
进阶:listAdapterOf 让数据更新自带 Diff 动画
数据动态变化的列表更推荐listAdapterOf()(recyclerview/src/main/java/com/tunjid/androidx/recyclerview/ComposedListAdapter.kt)。它在组合式写法之上直接内置了DiffUtil:调用submitList(newList),插入、删除、移动的动画就自动完成。
项目里蓝牙扫描页(app/src/main/java/com/tunjid/androidx/tabcomms/ble/BleScanFragment.kt)就是这样把实时扫描到的设备平滑刷新进列表的:
val listAdapter = listAdapterOf( initialItems = listOf(), viewHolderCreator = { parent, _ -> parent.viewHolderFrom(ViewholderScanBinding::inflate) }, viewHolderBinder = { holder, result, _ -> holder.bind(result) } ) adapter = listAdapter // ViewModel 数据变化时: viewModel.state.mapDistinct(BleState::items) .observe(viewLifecycleOwner, listAdapter::submitList)如果数据项想参与精确 diff,可以让它实现Diffable接口(recyclerview/src/main/java/com/tunjid/androidx/recyclerview/diff/Diffable.kt),只需提供一个diffId,其余比较逻辑有默认实现。
不止 Adapter:一个模块搞定列表全家桶
ComposedAdapter 只是 RecyclerView 模块的冰山一角,同一目录里还有:
- ComposedEndlessScroller:几行代码实现上拉加载、无限滚动;
- RecyclerViewMultiScroller:同步多个列表的滚动,轻松搭出“表格”效果(见
app/src/main/java/com/tunjid/androidx/tablists/tables/); - Drag & Drop 支持:
SwipeDragTouchHelper让拖拽排序和侧滑删除不用手写触摸逻辑; - viewHolderDelegate 委托:把“当前绑定的数据”存成 ViewHolder 的属性,读起来像普通成员变量。
模块说明可参考recyclerview/README.md,示例 App 的完整演示代码在app/src/main/java/com/tunjid/androidx/tablists/下。
如何快速上手?
在build.gradle中添加依赖即可(构件托管在 Maven Central):
implementation 'com.tunjid.androidx:recyclerview:1.x.x'然后记住三句话:
- 静态数据列表→ 用
adapterOf(),传数据源 + 创建函数 + 绑定函数; - 动态数据列表→ 用
listAdapterOf(),配合submitList()自动 diff; - ViewHolder→ 用
viewHolderFrom()从 ViewBinding 直接生成,不写子类。
从此,“组合”代替“继承”,你的 RecyclerView 代码量可以砍掉一半,而且逻辑全部集中在一个函数调用里,读起来一目了然。
【免费下载链接】Android-ExtensionsAn Android library with modules to quickly bootstrap an Android application.项目地址: https://gitcode.com/gh_mirrors/an/Android-Extensions
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考