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

RecyclerView拖拽场景下如何在拖拽结束时触发函数避免onMove重复调用

解决方案

你可以通过重写ItemTouchHelper.SimpleCallback的clearView()方法实现需求,该方法会在拖拽动作完全结束、用户松开条目时回调,仅触发一次,完全避免拖拽过程中的频繁调用开销。

修改后的代码如下:

val itemTouchHelper = ItemTouchHelper(simpleCallback)
itemTouchHelper.attachToRecyclerView(recyclerView)

private var simpleCallback = object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP.or(ItemTouchHelper.DOWN), 0) {
    override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
        val startPosition = viewHolder.absoluteAdapterPosition
        val endPosition = target.absoluteAdapterPosition

        Collections.swap(itemList, startPosition, endPosition)
        recyclerView.adapter?.notifyItemMoved(startPosition, endPosition)

        return true
    }

    // 新增重写clearView方法,拖拽结束时触发
    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
        super.clearView(recyclerView, viewHolder)
        expensiveFunction()
    }
}

可选精准控制(适配同时开启滑动删除的场景)

如果你的场景同时支持滑动删除,想要确保仅拖拽结束才触发计算,可以增加状态判断:

private var simpleCallback = object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP.or(ItemTouchHelper.DOWN), 0) {
    // 标记当前是否是拖拽状态
    private var isDragging = false

    override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
        val startPosition = viewHolder.absoluteAdapterPosition
        val endPosition = target.absoluteAdapterPosition
        Collections.swap(itemList, startPosition, endPosition)
        recyclerView.adapter?.notifyItemMoved(startPosition, endPosition)
        return true
    }

    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
        super.onSelectedChanged(viewHolder, actionState)
        // 记录是否进入拖拽状态
        isDragging = actionState == ItemTouchHelper.ACTION_STATE_DRAG
    }

    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
        super.clearView(recyclerView, viewHolder)
        // 仅拖拽结束时执行计算
        if (isDragging) {
            expensiveFunction()
            isDragging = false
        }
    }
}

额外优化建议

如果expensiveFunction()耗时较长,建议放到协程或子线程中执行,避免阻塞主线程导致UI卡顿。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:54:03