Android ItemTouchHelper 滑动RecyclerView条目时如何绘制逐步放大的圆形
实现RecyclerView滑动时圆形扩散背景的方案
核心实现逻辑
- 基于滑动距离计算滑动进度,将进度映射为圆形半径,实现随滑动放大的效果
- 直接使用
Canvas.drawCircle绘制圆形,避免Drawable宽高不一致导致的拉伸变形问题 - 裁剪画布绘制区域,限制圆形仅在当前条目范围内显示,不会覆盖其他列表项
完整实现代码
提前初始化画笔和图标,避免在绘制方法中重复创建影响性能:
// 提前初始化背景画笔 private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = Color.parseColor("#ba000d") } // 提前加载删除图标 private val deleteIcon: Drawable? = ContextCompat.getDrawable(context, R.drawable.ic_baseline_delete_24) override fun onChildDraw( c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean ) { val itemView = viewHolder.itemView // 仅处理左滑逻辑,右滑可修改判断条件为dX<=0 if (actionState != ItemTouchHelper.ACTION_STATE_SWIPE || dX >= 0) { super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) return } // 1. 计算滑动进度,范围0~1 val swipeProgress = abs(dX) / itemView.width.coerceAtLeast(1) val progress = swipeProgress.coerceAtMost(1f) // 2. 计算圆形参数:圆心为当前条目中心点,最大半径为刚好覆盖整个条目的半径 val centerX = itemView.left + itemView.width / 2f val centerY = itemView.top + itemView.height / 2f val maxRadius = hypot(itemView.width / 2f, itemView.height / 2f) val currentRadius = maxRadius * progress // 3. 裁剪画布,限制绘制范围仅为当前条目区域 c.save() c.clipRect(itemView.left, itemView.top, itemView.right, itemView.bottom) // 4. 绘制扩散圆形背景 c.drawCircle(centerX, centerY, currentRadius, backgroundPaint) // 5. 绘制删除图标,固定在条目右侧垂直居中 deleteIcon?.let { icon -> val iconSize = icon.intrinsicHeight val iconMargin = (itemView.height - iconSize) / 2 val iconLeft = itemView.right - iconMargin - iconSize val iconTop = itemView.top + (itemView.height - iconSize) / 2 icon.setBounds(iconLeft, iconTop, iconLeft + iconSize, iconTop + iconSize) // 图标随滑动进度逐步显示 icon.alpha = (progress * 255).toInt() icon.draw(c) } c.restore() // 调用父类方法绘制滑动的条目内容,保证条目在背景上层 super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) }
适配调整说明
- 如果需要圆形从条目侧边而非中心点开始扩散,只需修改
centerX的取值为对应侧边坐标即可 - 如需修改圆形的颜色、图标样式,直接修改画笔颜色和图标资源即可
内容的提问来源于stack exchange,提问作者Steven Rathmann
相关产品推荐
相关产品推荐

