Android Kotlin中如何移除Path的部分区域?(android.graphics)
解决Canvas中移除Path与圆形相交区域的问题
有两种常用方案可以实现你的需求,下面结合你的代码场景具体说明:
方案1:使用Paint的Xfermode实现擦除效果
这是最直接的方式,利用PorterDuff.Mode.CLEAR模式在绘制时清除指定区域的内容。需要注意的是,硬件加速可能会影响CLEAR模式的表现,建议在自定义View的构造方法中关闭硬件加速,或者使用saveLayer隔离绘制区域,避免误清除View背景。
示例修改你的onDraw方法:
override fun onDraw(canvas: Canvas) { super.onDraw(canvas) // 绘制已保存的所有路径 for(mPath: Path in mDrawing){ canvas.drawPath(mPath, paint) } // 绘制当前正在绘制的路径 canvas.drawPath(path, paint) // 配置擦除用的Paint val erasePaint = Paint().apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) isAntiAlias = true } // 假设要擦除的圆形:圆心(eraseX, eraseY),半径eraseRadius val layerId = canvas.saveLayer(0f, 0f, width.toFloat(), height.toFloat(), null) canvas.drawCircle(eraseX, eraseY, eraseRadius, erasePaint) canvas.restoreToCount(layerId) }
如果要实现跟随触摸的擦除笔,只需在触摸事件中记录擦除圆形的位置,在onDraw中循环绘制这些擦除区域即可。
方案2:使用Path.op进行路径布尔运算
如果需要永久修改Path对象(从原Path中移除相交区域),可以用Path.op对原Path和圆形Path做差集运算:
// 创建圆形路径 private fun getCirclePath(x: Float, y: Float, radius: Float): Path { val circlePath = Path() circlePath.addCircle(x, y, radius, Path.Direction.CW) return circlePath } // 移除已保存路径中与圆形相交的部分 fun erasePathByCircle(x: Float, y: Float, radius: Float) { val circlePath = getCirclePath(x, y, radius) val iterator = mDrawing.iterator() while (iterator.hasNext()) { val originPath = iterator.next() val newPath = Path(originPath) // 复制原路径,避免修改原始数据 // 差集运算:newPath = 原路径 - 圆形路径 if (newPath.op(circlePath, Path.Op.DIFFERENCE)) { iterator.remove() mDrawing.add(newPath) } } invalidate() // 触发重绘 }
调用erasePathByCircle后,原Path中与圆形相交的部分会被永久移除,后续绘制时不再显示该区域。
注意:Path.op对复杂路径的运算可能存在性能开销,若你的绘图包含大量复杂路径,优先选择方案1的Xfermode方式。
内容的提问来源于stack exchange,提问作者Leonard B.
相关产品推荐
相关产品推荐

