您还可以为您的 Composables 使用自定义形状来给它们一个特定的轮廓。只需扩展 Shape 接口并覆盖 createOutline() 方法。
例如:
对于角落,Path API 提供了一个 arcTo() 函数。然后,要绘制形状的边缘,请使用 lineTo() 方法。
class RoundedRectOutlinedCorner(
private val cornerRadius: Dp = 16.dp,
private val cutOutHeight: Dp = 60.dp,
private val cutOutWidth: Dp = 145.dp
) : Shape {
override fun createOutline(
size: Size, layoutDirection: LayoutDirection, density: Density
): Outline {
return Outline.Generic(Path().apply {
val cornerRadius = with(density) { cornerRadius.toPx() }
val cutOutHeight = with(density) { cutOutHeight.toPx() }
val cutOutWidth = with(density) { cutOutWidth.toPx() }
arcTo(
rect = Rect(offset = Offset(0f, 0f), Size(cornerRadius, cornerRadius)),
startAngleDegrees = 180f,
sweepAngleDegrees = 90f,
forceMoveTo = false
)
lineTo(size.width - cutOutWidth - cornerRadius, 0f)
arcTo(
rect = Rect(
offset = Offset(size.width - cutOutWidth - cornerRadius, 0f),
Size(cornerRadius, cornerRadius)
), startAngleDegrees = 270.0f, sweepAngleDegrees = 90f, forceMoveTo = false
)
lineTo(size.width - cutOutWidth, cutOutHeight - cornerRadius)
arcTo(
rect = Rect(
offset = Offset(size.width - cutOutWidth, cutOutHeight - cornerRadius),
Size(cornerRadius, cornerRadius)
), startAngleDegrees = 180.0f, sweepAngleDegrees = -90f, forceMoveTo = false
)
lineTo(size.width - cornerRadius, cutOutHeight)
arcTo(
rect = Rect(
offset = Offset(size.width - cornerRadius, cutOutHeight),
Size(cornerRadius, cornerRadius)
), startAngleDegrees = 270f, sweepAngleDegrees = 90f, forceMoveTo = false
)
lineTo(size.width, size.height - cornerRadius)
arcTo(
rect = Rect(
offset = Offset(size.width - cornerRadius, size.height - cornerRadius),
Size(cornerRadius, cornerRadius)
), startAngleDegrees = 0f, sweepAngleDegrees = 90f, forceMoveTo = false
)
lineTo(cornerRadius, size.height)
arcTo(
rect = Rect(
offset = Offset(0f, size.height - cornerRadius),
Size(cornerRadius, cornerRadius)
), startAngleDegrees = 90f, sweepAngleDegrees = 90f, forceMoveTo = false
)
close()
})
}
}
使用方法:
然后,您可以通过以下方式剪裁形状:
Modifier
.height(250.dp)
.clip(RoundedRectOutlinedCorner()),
或者使用.graphicsLayer/.background等。
结果:
![enter image description here](https://istack.dev59.com/2Apre.webp)