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

Android中如何从Adapter删除多个选中位置的条目?

问题分析与解决方案

错误原因

你的代码存在两个关键问题:

  • 误用循环索引i作为items的删除位置,而非传入的listOfDeleteItemPosition中的目标位置,这直接导致删除的位置完全不符合预期。
  • 即便修正为使用listOfDeleteItemPosition[i],删除元素后后续元素的索引会整体前移,导致原始位置失效。比如先删位置1,原本的位置7会变成6,此时再删7就会操作错误的元素,甚至触发索引越界异常。

正确实现方式

方式一:从后往前删除(推荐,保留删除动画)

核心思路是先将待删除位置按降序排序,从最大的位置开始删除,这样前面的元素位置不会因后续删除而变动,确保每个位置都是当前列表的有效索引。

修正后的代码:

override fun removeDataAtPosition(listOfDeleteItemPosition: ArrayList<Int>) {
    // 对位置列表降序排序,确保从后往前删除
    listOfDeleteItemPosition.sortDescending()
    for (position in listOfDeleteItemPosition) {
        // 边界判断,避免索引越界
        if (position in 0 until items.size) {
            items.removeAt(position)
            notifyItemRemoved(position)
        }
    }
}

方式二:批量过滤保留元素(简洁,无逐行动画)

如果不需要单个条目的删除动画,可以直接过滤出需要保留的元素,替换原列表后刷新:

override fun removeDataAtPosition(listOfDeleteItemPosition: ArrayList<Int>) {
    val removeSet = listOfDeleteItemPosition.toHashSet()
    val newItems = items.filterIndexed { index, _ -> !removeSet.contains(index) }
    val oldSize = items.size
    items.clear()
    items.addAll(newItems)
    // 通知RecyclerView数据变化,也可以用notifyDataSetChanged()
    notifyItemRangeRemoved(0, oldSize - newItems.size)
}

两种方式对比

  • 方式一:逐个删除并调用notifyItemRemoved,能触发RecyclerView的删除动画,用户体验更好,适合需要动画的场景。
  • 方式二:批量更新列表,代码更简洁,但没有单个条目的删除动画,适合对动画无要求的批量操作场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 09:40:09