You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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])

注意事项

如果你的列表同类型连续条目较多,不用强制拆成单条目适配器,可以把连续的同类型数据做成一个子适配器,插入到对应位置即可,能进一步减少适配器的创建开销。
如果你的两类适配器使用的viewType id不会重复,可以在构建ConcatAdapter时设置setIsolateViewTypes(false),能提升渲染性能。

内容的提问来源于stack exchange,提问作者ybybyb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 06:36:03