使用 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()
}
}
你会得到这样的东西:
我正在尝试使用 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()
}
}
你会得到这样的东西: