如何使用jetpack compose android在卡片视图的顶端绘制曲线或圆弧?

问题描述 投票:0回答:1

我正在尝试使用 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()

}

enter image description here

android kotlin android-jetpack-compose curve bezier
1个回答
0
投票

您应该使用

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))
)
© www.soinside.com 2019 - 2024. All rights reserved.