使用 Jetpack Compose 自定义形状 Android

Customize shapes with Jetpack Compose Android

我正在尝试使用 Jetpack Compose 为 Android 视图创建自定义形状,示例如下:

我不知道如何为这个形状创建小波浪 (top/bottom)。我需要有一个盒子和一个自定义形状吗?因为我需要在这个形状中添加一些文字。

如何使用 Jetpack Compose 创建此元素?

您需要自定义形状:

class CustomShape(private val waveCount: Int = 20): Shape {
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        return Outline.Generic(
            path = drawCustomPath(size, waveCount)
        )
    }
}

大纲路径:

fun drawCustomPath(size: Size, waveCount: Int): Path {
    val waveLength = size.width / (waveCount + 1)
    val waveHeight = waveLength / 5
    val gap = 3*waveLength/4
    return Path().apply {
        reset()
        moveTo(0f, 0f)
        arcTo(
            rect = Rect(topLeft = Offset(-waveLength/4, 0f),
                bottomRight = Offset(waveLength / 4, waveHeight)),
            startAngleDegrees = 270f,
            sweepAngleDegrees = 90f,
            forceMoveTo = false
        )
        arcTo(
            rect = Rect(topLeft = Offset(waveLength / 4, 0f),
                bottomRight = Offset(gap, waveHeight)),
            startAngleDegrees = 180f,
            sweepAngleDegrees = -180f,
            forceMoveTo = false
        )
        for (i in 1..waveCount) {
            arcTo(
                rect = Rect(topLeft = Offset(gap + waveLength * (i-1), 0f),
                    bottomRight = Offset(gap + waveLength * (i-1) + waveLength/2, waveHeight)),
                startAngleDegrees = 180f,
                sweepAngleDegrees = 180f,
                forceMoveTo = false
            )
            arcTo(
                rect = Rect(topLeft = Offset(gap + waveLength * (i-1) + waveLength/2, 0f),
                    bottomRight = Offset(gap + waveLength * i, waveHeight)),
                startAngleDegrees = 180f,
                sweepAngleDegrees = -180f,
                forceMoveTo = false
            )
        }
        arcTo(
            rect = Rect(topLeft = Offset(size.width - waveLength/4, 0f),
                bottomRight = Offset(size.width + waveLength/4, waveHeight)),
            startAngleDegrees = 180f,
            sweepAngleDegrees = 90f,
            forceMoveTo = false
        )
        lineTo(size.width, size.height)
        arcTo(
            rect = Rect(
                topLeft = Offset(size.width - waveLength/4, size.height - waveHeight),
                bottomRight = Offset(size.width + waveLength/4, size.height)),
            startAngleDegrees = 90f,
            sweepAngleDegrees = 90f,
            forceMoveTo = false
        )
        arcTo(
            rect = Rect(
                topLeft = Offset(size.width - gap,
                    size.height - waveHeight),
                bottomRight = Offset(size.width - waveLength/4, size.height)),
            startAngleDegrees = 0f,
            sweepAngleDegrees = -180f,
            forceMoveTo = false
        )
        for (i in 1..waveCount) {
            arcTo(rect = Rect(
                topLeft = Offset(size.width - gap - waveLength*(i-1) - waveLength/2,
                    size.height - waveHeight),
                bottomRight = Offset(size.width - gap - waveLength*(i-1),
                    size.height)),
                startAngleDegrees = 0f,
                sweepAngleDegrees = 180f,
                forceMoveTo = false
            )
            arcTo(
                rect = Rect(
                    topLeft = Offset(size.width - gap - waveLength * i,
                        size.height - waveHeight),
                    bottomRight = Offset(size.width - gap - waveLength*(i-1) - waveLength/2,
                        size.height)),
                startAngleDegrees = 0f,
                sweepAngleDegrees = -180f,
                forceMoveTo = false
            )
        }
        arcTo(
            rect = Rect(topLeft = Offset(-waveLength/4, size.height - waveHeight),
                bottomRight = Offset(waveLength/4, size.height)),
            startAngleDegrees = 0f,
            sweepAngleDegrees = 90f,
            forceMoveTo = false
        )
        close()
    }
}

你会得到这样的东西: