如何在Jetpack Compose中绘制指定尺寸的曲线形状?
Jetpack Compose 实现指定曲线形状绘制
针对你需要的宽333dp、高70dp的曲线形状,下面是调整后的Path实现方案,重点修正了拐角和曲线的控制逻辑:
@Composable fun CustomCurveShape() { val shapeWidth = 333.dp val shapeHeight = 70.dp val cornerRadius = 8.dp // 控制拐角圆润度,可按需修改 val curveSideOffset = 12.dp // 右侧曲线的水平偏移量,调整曲线位置 Canvas(modifier = Modifier.size(shapeWidth, shapeHeight)) { val widthPx = size.width val heightPx = size.height val cornerRadiusPx = cornerRadius.toPx() val curveOffsetPx = curveSideOffset.toPx() val path = Path().apply { // 起点:左上角圆角结束位置 moveTo(0f, cornerRadiusPx) // 左上角圆角 arcTo( rect = Rect(0f, 0f, cornerRadiusPx * 2, cornerRadiusPx * 2), startAngleDegrees = 180f, sweepAngleDegrees = 90f, forceMoveTo = false ) // 顶部直线到右侧曲线起始点 lineTo(widthPx - curveOffsetPx - cornerRadiusPx, 0f) // 右侧曲线:用三次贝塞尔实现平滑过渡 cubicTo( widthPx - curveOffsetPx, 0f, // 顶部控制点,贴合顶部边缘 widthPx, heightPx / 2, // 中间控制点,控制曲线弧度 widthPx - curveOffsetPx, heightPx // 曲线终点,贴合底部边缘 ) // 底部直线到右下角圆角起始点 lineTo(widthPx - curveOffsetPx - cornerRadiusPx, heightPx) // 右下角圆角 arcTo( rect = Rect( widthPx - curveOffsetPx - cornerRadiusPx * 2, heightPx - cornerRadiusPx * 2, widthPx - curveOffsetPx, heightPx ), startAngleDegrees = 0f, sweepAngleDegrees = 90f, forceMoveTo = false ) // 底部直线到左下角圆角起始点 lineTo(cornerRadiusPx, heightPx) // 左下角圆角 arcTo( rect = Rect(0f, heightPx - cornerRadiusPx * 2, cornerRadiusPx * 2, heightPx), startAngleDegrees = 90f, sweepAngleDegrees = 90f, forceMoveTo = false ) // 左侧直线回到起点 lineTo(0f, cornerRadiusPx) close() } // 填充形状 drawPath(path, color = Color(0xFF2196F3)) // 可选:绘制边框,方便调试形状 drawPath(path, color = Color.Black, style = Stroke(width = 1.dp.toPx())) } }
关键调整说明
- 拐角处理:用
arcTo替代cubicTo实现圆角拐角,能精准控制拐角的圆润度,避免手动计算贝塞尔控制点导致的形状偏差。 - 右侧曲线控制:通过三次贝塞尔曲线的两个控制点,让曲线从顶部平滑过渡到底部:
- 第一个控制点锚定在顶部偏移位置,保证曲线起始处贴合顶部边缘
- 第二个控制点放在右侧中间位置,控制曲线的弯曲幅度,你可以修改这个点的y值(比如
heightPx * 0.4f)来调整曲线弧度
- 尺寸统一转换:所有dp单位都转换为像素,确保在不同分辨率设备上形状一致。
自定义调整建议
- 如果拐角还是不符合预期,直接修改
cornerRadius的数值即可调整圆角大小 - 若右侧曲线形态不对,调整
curveSideOffset或cubicTo中的控制点坐标,直到匹配目标形状 - 若需要更复杂的曲线分段,可以拆分多个
cubicTo或使用quadraticTo(二次贝塞尔)简化控制
内容的提问来源于stack exchange,提问作者Yogesh Nikam Patil
相关产品推荐
相关产品推荐

