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

Android RecyclerView拖拽时Item移动过程中消失问题求助

解决RecyclerView拖拽Item时消失的问题

核心问题定位

你的代码中**onItemMove方法的反向交换逻辑存在错误**,当从高位索引向低位索引拖拽时,循环根本不会执行,导致数据集合未正确更新,RecyclerView无法正确计算Item位置,最终出现拖拽时Item移出屏幕消失的情况。

错误代码分析

原onItemMove中,当fromPosition > toPosition时,使用了for (i in fromPosition until toPosition)循环:

// 错误逻辑:fromPosition > toPosition时,fromPosition until toPosition是无效区间,循环不会执行
for (i in fromPosition until toPosition) {
    Collections.swap(cities, i, i - 1)
}

until是左闭右开的区间,当起始值大于结束值时,区间为空,循环体完全不执行,导致数据集合的元素位置没有交换,但你调用了notifyItemMoved,这会让RecyclerView的布局计算出现混乱。

修复后的代码

把反向循环改为从fromPosition递减到toPosition + 1:

override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
    if (fromPosition < toPosition) {
        for (i in fromPosition until toPosition) {
            Collections.swap(cities, i, i + 1)
        }
    } else {
        // 改为递减循环,确保每一步都交换相邻元素
        for (i in fromPosition downTo toPosition + 1) {
            Collections.swap(cities, i, i - 1)
        }
    }
    notifyItemMoved(fromPosition, toPosition)
    return true
}

额外优化建议

  1. 统一索引判断逻辑:在DragAndDropCallback的getMovementFlags中,判断拖拽权限的逻辑可以简化,避免区间判断出错:
override fun getMovementFlags(
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder
): Int {
    val position = viewHolder.bindingAdapterPosition
    val dragFlags = if (position != 0 && position != adapter.itemCount - 1) {
        ItemTouchHelper.UP or ItemTouchHelper.DOWN
    } else {
        0
    }
    return makeMovementFlags(dragFlags, 0)
}
  1. 关闭不需要的滑动功能:你的场景不需要滑动删除,建议把isItemViewSwipeEnabled改为false,避免不必要的交互干扰:
override fun isItemViewSwipeEnabled(): Boolean {
    return false
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 22:57:26