#kotlin #android-jetpack-compose #android-jetpack-compose-canvas
Вопрос:
У меня был вопрос о создании этого представления в Compose, и я понятия не имею о его реализации.
Мой текущий код выглядит так:
Box(
modifier = Modifier
.fillMaxSize()
.height(300.dp)
) {
Canvas(modifier = Modifier.matchParentSize()) {
drawRoundRect(
color = Color.Yellow,
cornerRadius = CornerRadius(16.dp.toPx(), 16.dp.toPx())
)
drawRoundRect(
color = Color.White,
topLeft = Offset(
x = size.width / 5,
y = size.height - 60.dp.toPx()
),
size = Size((size.width / 5) * 3, 50.dp.toPx() * 2),
cornerRadius = CornerRadius(24.dp.toPx(), 24.dp.toPx()),
)
}
Box(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
Text(
text = "Test",
modifier = Modifier.align(Alignment.BottomCenter)
)
}
}
Результатом является следующее:
Ответ №1:
Чтобы отрезать какой-то путь от другого пути, вы можете использовать clipPath
.
А для внешнего радиуса угла вам нужно вручную добавить дуги к контуру, вот так:
Canvas(modifier = Modifier.matchParentSize()) {
val outerCornerRadius = 16.dp.toPx()
val clippedPath = Path().apply {
val innerCornerRadius = 24.dp.toPx()
val rectSize = Size(round((size.width / 5) * 3), round(50.dp.toPx() * 2))
val rect = Rect(
offset = Offset(
x = (size.width - rectSize.width) / 2,
y = size.height - rectSize.height
),
size = rectSize
)
addRoundRect(
RoundRect(
rect,
topLeft = CornerRadius(x = innerCornerRadius, y = innerCornerRadius),
topRight = CornerRadius(x = innerCornerRadius, y = innerCornerRadius),
)
)
val outerCornerDiameter = outerCornerRadius * 2
val cornerSize = Size(outerCornerDiameter,outerCornerDiameter)
val cornerOffset = Offset(outerCornerDiameter, outerCornerDiameter)
val cornerYOffset = Offset(0f, outerCornerDiameter)
moveTo(rect.bottomLeft - cornerYOffset)
addArc(
Rect(
offset = rect.bottomLeft - cornerOffset,
size = cornerSize
),
startAngleDegrees = 0f,
sweepAngleDegrees = 90f,
)
lineTo(rect.bottomLeft)
moveTo(rect.bottomRight - cornerYOffset)
addArc(
Rect(
offset = rect.bottomRight - cornerYOffset,
size = cornerSize
),
startAngleDegrees = 180f,
sweepAngleDegrees = -90f,
)
lineTo(rect.bottomRight)
}
clipPath(clippedPath, clipOp = ClipOp.Difference) {
drawRoundRect(
color = Color.Yellow,
cornerRadius = CornerRadius(outerCornerRadius, outerCornerRadius)
)
}
}
Результат: