Android中如何实现View底部中心的平滑弧形效果?
底部中心弧形平滑优化方案
你的代码出现尖角的核心原因是:addRoundRect生成的路径与后续手动添加的贝塞尔曲线、直线段衔接时,路径出现重叠和方向冲突,导致拐角处无法平滑过渡。
优化后的完整代码
class CustomCurvedView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : View(context, attrs, defStyleAttr) { private val paint = Paint().apply { color = 0xFF4CAF50.toInt() style = Paint.Style.FILL isAntiAlias = true } private val path = Path() private val cornerRadius = 50f private val curveHeight = 100f private val curveWidth = 200f override fun onDraw(canvas: Canvas) { super.onDraw(canvas) val width = width.toFloat() val height = height.toFloat() val rectTopHeight = height - curveHeight path.reset() // 绘制顶部水平线(跳过左右圆角区域) path.moveTo(cornerRadius, 0f) path.lineTo(width - cornerRadius, 0f) // 绘制右上角圆角 path.arcTo( RectF(width - 2 * cornerRadius, 0f, width, 2 * cornerRadius), 270f, 90f ) // 绘制右侧垂直线到弧形右起点 path.lineTo(width, rectTopHeight) // 绘制底部中心平滑贝塞尔弧形 val curveLeftX = width / 2 - curveWidth / 2 val curveRightX = width / 2 + curveWidth / 2 path.cubicTo( curveRightX - curveWidth / 4, rectTopHeight, // 右侧控制点 curveLeftX + curveWidth / 4, height, // 左侧控制点 curveLeftX, rectTopHeight // 弧形左终点 ) // 绘制左侧垂直线到左上角圆角起点 path.lineTo(0f, rectTopHeight) // 绘制左下角圆角 path.arcTo( RectF(0f, 0f, 2 * cornerRadius, 2 * cornerRadius), 180f, 90f ) path.close() canvas.drawPath(path, paint) } }
关键优化说明
- 废弃
addRoundRect:改为手动分模块绘制圆角、直线和弧形,确保路径全程连续,避免自动生成的矩形路径与后续弧形产生节点冲突。 - 调整贝塞尔控制点:将右侧控制点与弧形起点保持同一高度,左侧控制点下移到底部中心,让弧形从左右两侧自然过渡,彻底消除尖角。
- 路径无缝衔接:所有线段的起点与前一段的终点严格对齐,保证整个封闭路径没有断裂或重叠的节点,实现全边缘平滑。
可选调整方向
如果需要更圆润的弧形效果,可以将贝塞尔曲线替换为arcTo绘制标准圆弧,或者微调curveWidth与curveHeight的比例,适配不同的视觉需求。
内容的提问来源于stack exchange,提问作者Ghouse P
相关产品推荐
相关产品推荐

