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

使用ItemTouchHelper删除Adapter条目后无法滑动的问题

问题分析与解决方案

我帮你排查了代码里的几个核心问题,这就是删除第一个条目后无法继续滑动的根源:

1. 只读集合的修改异常

你的data变量定义成了List<User>,这是Kotlin的只读集合,本身没有removeAt()方法。调用data.removeAt(position)会直接抛出UnsupportedOperationException,导致后续的notifyItemRemoved()和notifyItemRangeChanged()都无法执行。这会让RecyclerView的UI状态和数据源完全脱节,后续的滑动逻辑自然就失效了。

修复方法:

把data改为可变集合MutableList:

class Adapter: RecyclerView.Adapter<BaseUserVH>() { 
    private var data: MutableList<User> = mutableListOf() // 替换为MutableList
    private var activeUserPosition = 0 
    // ... 其他代码保持不变
}

2. Active位置未同步更新

当你删除的条目位置小于等于activeUserPosition时,activeUserPosition没有同步调整,会导致后续条目的ViewType判断错误(比如原来的第二个条目现在变成position 0,但activeUserPosition还是0,会被错误标记为Active类型)。虽然这不是直接导致滑动失效的原因,但会引发其他UI异常,建议一起修复。

修复方法:

在updateItemRemoved()里同步更新activeUserPosition:

fun updateItemRemoved(position: Int) { 
    data.removeAt(position) 
    // 如果删除的是active条目或active位置在删除位置之后,调整索引
    if (activeUserPosition >= position) {
        activeUserPosition = max(0, activeUserPosition - 1)
    }
    notifyItemRemoved(position) 
    notifyItemRangeChanged(position, itemCount) 
}

3. 使用更可靠的Position获取方式

在ItemTouchHelper的onSwiped()中,你用了viewHolder.layoutPosition,但更可靠的是viewHolder.adapterPosition——它代表条目在Adapter中的最新位置,能避免因布局未及时更新导致的位置错误。

修复方法:

修改swipeToDelete里的回调逻辑:

override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { 
    val position = viewHolder.adapterPosition
    if (position != RecyclerView.NO_POSITION) { // 额外判断,避免无效位置
        onSwiped(position) 
    }
}

4. 滑动限制逻辑的潜在优化

你的getMovementFlags里判断了只剩最后一个条目时禁止滑动,这个逻辑没问题,但如果activeUserPosition对应的条目你不希望被滑动,可以补充判断:

override fun getMovementFlags( 
    recyclerView: RecyclerView, 
    viewHolder: RecyclerView.ViewHolder 
): Int {
    val position = viewHolder.adapterPosition
    if (position == RecyclerView.NO_POSITION) return 0
    // 如果是active条目,禁止滑动(根据你的业务需求调整)
    if (position == activeUserPosition) return 0
    // 原有的最后一个条目禁止滑动逻辑
    return if (adapter?.itemCount ?: 0 == 1 && position == 0) 0 else super.getMovementFlags(recyclerView, viewHolder)
}

把这些修改都应用后,滑动删除的逻辑就能正常工作了。


内容的提问来源于stack exchange,提问作者P.Juni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:02:50