我正在尝试使用 jetpack compose 在卡片视图或布局的右上角绘制一条曲线。我想在带有浮动按钮的视图右侧绘制一条曲线,并使用喷气背包组成,就像所附图像一样。
我尝试通过贝塞尔曲线来实现这一点,但只能在中心绘制曲线,而不是在右侧或左侧。 任何领导或帮助将不胜感激。
我的代码:
@可组合 有趣的 AreShapeOnBorderCenterSurface( 角半径:Dp, 中心圆半径:Dp, 内容:@Composable() -> 单位 ){
val density = LocalDensity.current
val cornerRadiusPx = density.run {
cornerRadius.toPx()
}
val centerCircleRadiusPx = density.run {
centerCircleRadius.toPx()
}
Surface(
modifier = Modifier
.fillMaxWidth(0.8f)
.wrapContentHeight(),
elevation = 5.dp,
color = Color.White,
shape = GenericShape { size: Size, _: LayoutDirection ->
buildCustomPath(size, cornerRadiusPx, centerCircleRadiusPx)
},
border = BorderStroke(1.dp, Color.Gray.copy(alpha = 0.6f))
) {
Box(
modifier = Modifier
.fillMaxWidth()
.padding(top = centerCircleRadius)
) {
content()
}
}
}
fun Path.buildCustomPath(大小:大小,cornerRadius:浮动,centerCircleRadius:浮动){ val 宽度 = 大小.宽度 val 高度 = 尺寸.高度
// 顶部简化计算的
val topHalfMoveLength = (width - 2 * cornerRadius - 2 * centerCircleRadius) / 2
// 单位长度
val smallCubeLength = centerCircleRadius / 20
val firstCubicPoint1 = Offset(
x = 1 * cornerRadius + topHalfMoveLength + 8 * smallCubeLength,
y = 1 * smallCubeLength
)
val firstCubicPoint2 = Offset(
x = 1 * cornerRadius + topHalfMoveLength + 4 * smallCubeLength,
y = 16 * smallCubeLength
)
val firstCubicTarget = Offset(
x = 1 * cornerRadius + topHalfMoveLength + centerCircleRadius,
y = 16 * smallCubeLength
)
val secondCubicPoint1 = Offset(
x = width - firstCubicPoint2.x,
y = firstCubicPoint2.y
)
val secondCubicPoint2 = Offset(
x = width - firstCubicPoint1.x,
y = firstCubicPoint1.y
)
val secondCubicTarget = Offset(
x = 1 * cornerRadius + topHalfMoveLength + 2 * centerCircleRadius,
y = 0f
)
moveTo(cornerRadius, 0f)
lineTo(cornerRadius + topHalfMoveLength, 0f)
cubicTo(
x1 = firstCubicPoint1.x,
y1 = firstCubicPoint1.y,
x2 = firstCubicPoint2.x,
y2 = firstCubicPoint2.y,
x3 = firstCubicTarget.x,
y3 = firstCubicTarget.y,
)
cubicTo(
x1 = secondCubicPoint1.x,
y1 = secondCubicPoint1.y,
x2 = secondCubicPoint2.x,
y2 = secondCubicPoint2.y,
x3 = secondCubicTarget.x,
y3 = secondCubicTarget.y,
)
lineTo(width - cornerRadius, 0f)
arcTo(
rect = Rect(
topLeft = Offset(x = width - 2 * cornerRadius, y = 0f),
bottomRight = Offset(x = width, y = 2 * cornerRadius)
),
startAngleDegrees = -90f,
sweepAngleDegrees = 90f,
forceMoveTo = false
)
lineTo(width, height - cornerRadius)
arcTo(
rect = Rect(
topLeft = Offset(x = width - 2 * cornerRadius, y = height - 2 * cornerRadius),
bottomRight = Offset(x = width, y = height)
),
startAngleDegrees = 0f,
sweepAngleDegrees = 90f,
forceMoveTo = false
)
lineTo(0f + cornerRadius, height)
arcTo(
rect = Rect(
topLeft = Offset(x = 0f, y = height - 2 * cornerRadius),
bottomRight = Offset(x = 2 * cornerRadius, y = height)
),
startAngleDegrees = 90f,
sweepAngleDegrees = 90f,
forceMoveTo = false
)
lineTo(0f, cornerRadius)
arcTo(
rect = Rect(
topLeft = Offset.Zero,
bottomRight = Offset(x = 2 * cornerRadius, y = 2 * cornerRadius)
),
startAngleDegrees = 180f,
sweepAngleDegrees = 90f,
forceMoveTo = false
)
close()
}
您应该使用
RoundedCornerShape
来代替 GenericShape
,例如:
Surface(
modifier = Modifier
.fillMaxWidth(0.8f)
.padding(20.dp)
.wrapContentHeight(),
elevation = 5.dp,
color = Color.White,
shape = RoundedCornerShape( topStart = 20.dp, topEnd = 20.dp, bottomEnd = 50.dp, bottomStart = 0.dp),
border = BorderStroke(1.dp, Color.Gray.copy(alpha = 0.6f))
)