Kotlin 拖拽过程中如何取消拖拽并让控件返回初始位置
解决方案
方案1:直接调用ItemTouchHelper公开的终止拖拽方法(适配AndroidX Recyclerview 1.2.0及以上版本)
从AndroidX Recyclerview 1.2.0版本开始,ItemTouchHelper新增了公开的endDrag()方法,调用后即可立即终止当前正在进行的拖拽动作,被拖拽的条目会自动回到拖拽开始前的原位:
fun cancelCurrentDragging() { // 直接调用endDrag即可终止拖拽 itemTouchHelper.endDrag() }
如果你的项目依赖的Recyclerview版本低于1.2.0,可以用下面的反射方案兼容:
fun cancelCurrentDraggingLowVersion() { try { val cancelMethod = ItemTouchHelper::class.java.getDeclaredMethod("cancel") cancelMethod.isAccessible = true cancelMethod.invoke(itemTouchHelper) } catch (e: Exception) { e.printStackTrace() } }
方案2:通用兼容方案(适配所有Recyclerview版本)
如果不想用反射,可以通过临时修改ItemTouchHelper.Callback的拖拽方向返回值实现强制终止:
- 先在你的
ItemTouchHelper.Callback实现类里加一个控制开关:
class MyItemTouchCallback : ItemTouchHelper.Callback() { // 控制是否允许拖拽的开关 var isDragEnabled = true override fun getMovementFlags( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { // 开关关闭时直接返回0,不允许任何拖拽/滑动动作 if (!isDragEnabled) { return makeMovementFlags(0, 0) } // 原来的逻辑,比如支持上下拖拽 return makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0) } // 剩下的onMove、onSwiped等原有逻辑保持不变 }
- 需要取消拖拽的时候执行以下代码:
fun cancelDragByCallback() { // 先关闭拖拽开关 myItemTouchCallback.isDragEnabled = false // 通知ItemTouchHelper状态更新,此时会强制终止当前拖拽,条目回到原位 itemTouchHelper.attachToRecyclerView(recyclerView) // 延迟恢复拖拽开关,不影响后续正常拖拽操作 recyclerView.post { myItemTouchCallback.isDragEnabled = true } }
内容的提问来源于stack exchange,提问作者J. Doe
相关产品推荐
相关产品推荐

