Kotlin中ListAdapter展示分类列表去重后索引越界如何解决?
问题解决方法
错误根源
- 你将去重逻辑放在
onBindViewHolder中属于错误用法:该方法会在每个列表项渲染时重复执行,频繁做flatMap、distinct操作会造成不必要的性能损耗。 - 抛出下标越界异常的核心原因是适配器返回的列表总长度和去重后的分类列表长度不匹配:你当前适配器的
getItemCount()方法大概率返回的是原始业务列表长度,或是去重前的全部分类列表长度,去重后分类列表变短,当position超过去重后列表的最大索引时就会触发越界。
修复步骤
- 在适配器内部单独维护一份提前处理好的去重分类列表作为专属数据源,不要在渲染时才做数据处理:
class YourCategoryAdapter( private val mylist: List<YourOriginalBean> ) : RecyclerView.Adapter<ListCatViewHolder>() { // 提前完成扁平化、去重操作,作为分类列表的唯一数据源 private val distinctCategories = mylist.flatMap { it.category }.distinct()
- 重写
getItemCount方法,返回去重后分类列表的长度:
override fun getItemCount(): Int = distinctCategories.size
- 修改
onBindViewHolder逻辑,直接从预处理好的列表中取对应位置的分类即可:
override fun onBindViewHolder(holder: ListCatViewHolder, position: Int) { val currentCategory = distinctCategories[position] holder.binding.txtCat.text = currentCategory.toString() } }
- 如果后续原始业务列表
mylist会动态更新,每次更新后同步重新计算distinctCategories,再调用notifyDataSetChanged()或者对应的局部刷新方法即可。
内容的提问来源于stack exchange,提问作者gkaro
相关产品推荐
相关产品推荐

