使用ConcatAdapter时如何自定义调整RecyclerView列表项的排列顺序?
你当前的用法无法实现穿插效果,因为ConcatAdapter的核心逻辑是按传入的子适配器顺序,依次拼接每个子适配器的全部列表项,你把所有A类数据放在同一个适配器、所有B类数据放在另一个适配器,自然只能得到全A+全B的排列。
要实现AB任意穿插的效果,需要把ConcatAdapter的子适配器拆分粒度和你要调整的条目粒度对齐,具体实现方式如下:
- 第一步:拆分细粒度的单类型适配器
你可以选择拆到「单个条目对应一个适配器」的粒度,也可以根据业务场景把连续的同类型条目做成一个适配器,后续按需插入到指定位置即可。
单条目适配器示例:
// 单条A类项适配器,仅承载1条数据 class SingleAAdapter(val item: RoutineModel) : RecyclerView.Adapter<SingleAAdapter.AViewHolder>() { override fun getItemCount() = 1 // 正常实现onCreateViewHolder、onBindViewHolder逻辑即可 // ... } // 单条B类项适配器,仅承载1条数据 class SingleBAdapter(val item: bModel) : RecyclerView.Adapter<SingleBAdapter.BViewHolder>() { override fun getItemCount() = 1 // 正常实现onCreateViewHolder、onBindViewHolder逻辑即可 // ... }
- 第二步:自行维护全局条目顺序
定义结构统一的条目类型,用一个列表全权管理所有条目的顺序、类型和对应数据,你可以按需随意调整这个列表的排列,实现任意AB穿插效果:
// 定义统一的条目类型 sealed class RoutineListItem { data class TypeA(val data: RoutineModel) : RoutineListItem() data class TypeB(val data: bModel) : RoutineListItem() } // 业务层维护的全局条目列表,顺序完全自定义 val itemList = mutableListOf<RoutineListItem>( RoutineListItem.TypeA(aModel("e","eqw","ewqe")), RoutineListItem.TypeB(bModel()), RoutineListItem.TypeA(aModel("e2","eqw2","ewqe2")), RoutineListItem.TypeB(bModel()), // 你想要什么排列就直接按顺序加就行 )
- 第三步:动态更新ConcatAdapter
ConcatAdapter本身支持按位置增删移子适配器,你调整完自己维护的条目列表后,同步调用对应方法更新ConcatAdapter即可,会自动触发RecyclerView的条目动画:
// 构建ConcatAdapter配置 val concatConfig = ConcatAdapter.Config.Builder() // 如果A、B适配器的viewType id不会重复,可设为false提升性能,默认true也能正常运行 .setIsolateViewTypes(true) .build() val concatAdapter = ConcatAdapter(concatConfig) // 首次加载时按列表顺序添加子适配器 itemList.forEach { item -> when(item) { is RoutineListItem.TypeA -> concatAdapter.addAdapter(SingleAAdapter(item.data)) is RoutineListItem.TypeB -> concatAdapter.addAdapter(SingleBAdapter(item.data)) } } // 示例:在第2位插入一个B类项 val newB = RoutineListItem.TypeB(bModel()) itemList.add(2, newB) concatAdapter.addAdapter(2, SingleBAdapter(newB.data)) // 示例:删除第3位的条目 itemList.removeAt(3) concatAdapter.removeAdapter(concatAdapter.adapters[3])
注意事项
如果你的列表同类型连续条目较多,不用强制拆成单条目适配器,可以把连续的同类型数据做成一个子适配器,插入到对应位置即可,能进一步减少适配器的创建开销。
如果你的两类适配器使用的viewTypeid不会重复,可以在构建ConcatAdapter时设置setIsolateViewTypes(false),能提升渲染性能。
内容的提问来源于stack exchange,提问作者ybybyb
相关产品推荐
相关产品推荐

