Android Kotlin:修改RecyclerView滑动删除方向为左滑至右
修改RecyclerView滑动删除方向为左滑至右(或支持自定义方向)
直接修改为左滑至右的版本
修改后的SwipeToDeleteCallback代码
abstract class SwipeToDeleteCallback(context: Context) : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) { private val deleteIcon = ContextCompat.getDrawable(context, R.drawable.ic_delete_white_24) private val intrinsicWidth = deleteIcon?.intrinsicWidth private val intrinsicHeight = deleteIcon?.intrinsicHeight private val background = GradientDrawable() private val color = ContextCompat.getColor(context, R.color.swipe_delete_color) private val clearPaint = Paint().apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) } override fun onMove( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean { return false } override fun onChildDraw( c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean ) { val itemView = viewHolder.itemView val itemHeight = itemView.bottom - itemView.top val isCanceled = dX == 0f && !isCurrentlyActive if (isCanceled) { // 清理左侧的绘制区域 clearCanvas(c, itemView.left.toFloat(), itemView.top.toFloat(), itemView.left + dX, itemView.bottom.toFloat()) super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) return } // 绘制删除背景 background.setColor(this.color) background.cornerRadius = 20.0f // 背景区域从左侧开始,随dX滑动扩展 background.setBounds(itemView.left, itemView.top, (itemView.left + dX).toInt(), itemView.bottom) background.draw(c) // 计算删除图标的位置 val deleteIconTop = itemView.top + (itemHeight - intrinsicHeight!!) / 2 val deleteIconMargin = (itemHeight - intrinsicHeight) / 2 val deleteIconLeft = itemView.left + deleteIconMargin val deleteIconRight = itemView.left + deleteIconMargin + intrinsicWidth!! val deleteIconBottom = deleteIconTop + intrinsicHeight // 绘制删除图标 deleteIcon?.setBounds(deleteIconLeft, deleteIconTop, deleteIconRight, deleteIconBottom) deleteIcon?.draw(c) super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) } private fun clearCanvas(c: Canvas?, left: Float, top: Float, right: Float, bottom: Float) { c?.drawRect(left, top, right, bottom, clearPaint) } }
MainActivity调用代码(无需修改)
val swipeHandler = object : SwipeToDeleteCallback(this) { override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { val adapter1 = recyclerView.adapter as StockCompanyListAdapter adapter1.removeAt(viewHolder.adapterPosition) } } val itemTouchHelper = ItemTouchHelper(swipeHandler) itemTouchHelper.attachToRecyclerView(recyclerView)
支持自定义滑动方向的通用版本
如果需要灵活切换左滑/右滑删除,可使用以下通用版本:
通用版SwipeToDeleteCallback代码
abstract class SwipeToDeleteCallback( context: Context, private val swipeDirection: Int // 传入ItemTouchHelper.LEFT或ItemTouchHelper.RIGHT ) : ItemTouchHelper.SimpleCallback(0, swipeDirection) { private val deleteIcon = ContextCompat.getDrawable(context, R.drawable.ic_delete_white_24) private val intrinsicWidth = deleteIcon?.intrinsicWidth private val intrinsicHeight = deleteIcon?.intrinsicHeight private val background = GradientDrawable() private val color = ContextCompat.getColor(context, R.color.swipe_delete_color) private val clearPaint = Paint().apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) } override fun onMove( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean { return false } override fun onChildDraw( c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean ) { val itemView = viewHolder.itemView val itemHeight = itemView.bottom - itemView.top val isCanceled = dX == 0f && !isCurrentlyActive if (isCanceled) { // 根据方向清理对应区域 if (swipeDirection == ItemTouchHelper.LEFT) { clearCanvas(c, itemView.right + dX, itemView.top.toFloat(), itemView.right.toFloat(), itemView.bottom.toFloat()) } else { clearCanvas(c, itemView.left.toFloat(), itemView.top.toFloat(), itemView.left + dX, itemView.bottom.toFloat()) } super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) return } // 根据方向绘制背景 background.setColor(this.color) background.cornerRadius = 20.0f if (swipeDirection == ItemTouchHelper.LEFT) { background.setBounds(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom) } else { background.setBounds(itemView.left, itemView.top, (itemView.left + dX).toInt(), itemView.bottom) } background.draw(c) // 根据方向计算图标位置 val deleteIconTop = itemView.top + (itemHeight - intrinsicHeight!!) / 2 val deleteIconMargin = (itemHeight - intrinsicHeight) / 2 val deleteIconLeft: Int val deleteIconRight: Int if (swipeDirection == ItemTouchHelper.LEFT) { deleteIconLeft = itemView.right - deleteIconMargin - intrinsicWidth!! deleteIconRight = itemView.right - deleteIconMargin } else { deleteIconLeft = itemView.left + deleteIconMargin deleteIconRight = itemView.left + deleteIconMargin + intrinsicWidth!! } val deleteIconBottom = deleteIconTop + intrinsicHeight // 绘制图标 deleteIcon?.setBounds(deleteIconLeft, deleteIconTop, deleteIconRight, deleteIconBottom) deleteIcon?.draw(c) super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) } private fun clearCanvas(c: Canvas?, left: Float, top: Float, right: Float, bottom: Float) { c?.drawRect(left, top, right, bottom, clearPaint) } }
调用方式(指定左滑至右)
val swipeHandler = object : SwipeToDeleteCallback(this, ItemTouchHelper.RIGHT) { override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { val adapter1 = recyclerView.adapter as StockCompanyListAdapter adapter1.removeAt(viewHolder.adapterPosition) } } val itemTouchHelper = ItemTouchHelper(swipeHandler) itemTouchHelper.attachToRecyclerView(recyclerView)
关键修改点说明
- 滑动方向参数:将
ItemTouchHelper.SimpleCallback的第二个参数从ItemTouchHelper.LEFT改为ItemTouchHelper.RIGHT(或通过参数动态传入),这是控制滑动方向的核心。 - 背景绘制区域:左滑至右时,背景从Item左侧开始随滑动距离扩展,而非右侧。
- 图标位置计算:图标从Item左侧的margin位置绘制,而非右侧。
- 画布清理逻辑:取消滑动时,清理对应方向的绘制区域,避免界面残留。
内容的提问来源于stack exchange,提问作者coder 534
相关产品推荐
相关产品推荐

