如何使用 Jetpack compose 绘制通用形状?
我想画roundedCornerCircle,但右侧应该有一条内曲线而不是外曲线。
我尝试在 roundedCornerShape 中给出负半径,但它不起作用。有人可以帮助我了解如何自定义它并在 Android Jetpack compose 中绘制它吗?
结果
如果您希望将其作为形状在此自定义形状的边界内可单击,您可以仅使用以下方法创建一个角位于左侧的圆角矩形:
val shape = GenericShape { size: Size, layoutDirection: LayoutDirection ->
val width = size.width
val height = size.height
addArc(
oval = Rect(
offset = Offset.Zero,
size = Size(height, height)
),
startAngleDegrees = 90f,
sweepAngleDegrees = 180f,
)
lineTo(width, 0f)
lineTo(width, height)
lineTo(height, height)
}
然后要剪辑右侧,您可以使用混合模式,如本问答中所示
Box(
modifier = Modifier
.size(200.dp, 100.dp)
.clip(shape)
.drawWithContent {
val width = size.width
val height = size.height
val radius = 30f
with(drawContext.canvas.nativeCanvas) {
val checkPoint = saveLayer(null, null)
// Destination
drawContent()
// Source
drawArc(
color = Color.Transparent,
startAngle = 90f,
sweepAngle = 180f,
topLeft = Offset(
width - radius, 0f
),
size = Size(2 * radius, height),
useCenter = false,
blendMode = BlendMode.SrcOut
)
restoreToCount(checkPoint)
}
}
.background(Yellow400)
.clickable {
}
)
全面实施
@Preview
@Composable
fun ShapePreview() {
Column(modifier = Modifier
.fillMaxSize()
.padding(20.dp)) {
val shape = GenericShape { size: Size, layoutDirection: LayoutDirection ->
val width = size.width
val height = size.height
addArc(
oval = Rect(
offset = Offset.Zero,
size = Size(height, height)
),
startAngleDegrees = 90f,
sweepAngleDegrees = 180f,
)
lineTo(width, 0f)
lineTo(width, height)
lineTo(height, height)
}
Box(
modifier = Modifier
.size(200.dp, 100.dp)
.clip(shape)
.drawWithContent {
val width = size.width
val height = size.height
// Change this as required, ra
val radius = 80f
with(drawContext.canvas.nativeCanvas) {
val checkPoint = saveLayer(null, null)
// Destination
drawContent()
// Source
drawArc(
color = Color.Transparent,
startAngle = 90f,
sweepAngle = 180f,
topLeft = Offset(
width - radius, 0f
),
size = Size(2 * radius, height),
useCenter = false,
blendMode = BlendMode.SrcOut
)
restoreToCount(checkPoint)
}
}
.background(Orange400)
.clickable {
}
)
}
}
如果您只需要在 DrawScope 中绘制它,则根本不需要 Shape。创建一个具有左侧圆边的 RoundedRect 并为右侧执行混合模式。
a) 通过实现
Shape 接口并覆盖其 createOutline 函数来创建自定义类 或
b) 使用GenericShape 并将构建器 lambda 传递给它。在底层,GenericShape 覆盖了 Shape 的 createOutline 函数。