use*_*265 4 android kotlin android-jetpack-compose
我想在具有角半径 (10dp) 的 Card 组件的上半部分添加边框。因此,只有底部缺失,卡片的其余部分的笔划为 1dp。(有点像U型和倒U型)
我想对具有底角半径且顶部缺失的卡片执行相同的操作。
我尝试设计自定义形状,但它不尊重卡片的形状。
// this is just a line but it doesn't respect the card corner radius?
private fun createShape(thickness: Float) : Shape {
return GenericShape { size, _ ->
moveTo(0f,0f)
lineTo(0f, size.height)
lineTo(thickness, size.height)
lineTo(thickness, 0f)
lineTo(0f, thickness)
}
}
val thickness = with(LocalDensity.current) {
1.dp.toPx()
}
Card(
shape = RoundedCornerShape(topEnd = 10.dp, topStart = 10.dp, bottomEnd = 0.dp, bottomStart = 0.dp),
modifier = Modifier
.border(BorderStroke(width = 1.dp, color = Color.Black), createShape(thickness))
) {
...
}
Run Code Online (Sandbox Code Playgroud)
边框似乎不允许打开形状,即使您绘制 3 条线,也会强制形状关闭,因为您需要使用 Modifier.drawBehind 或 Modifier.drawWithContent。
创建了一个Modifier
绘制 u 形边框的
fun Modifier.semiBorder(strokeWidth: Dp, color: Color, cornerRadiusDp: Dp) = composed(
factory = {
val density = LocalDensity.current
val strokeWidthPx = density.run { strokeWidth.toPx() }
val cornerRadius = density.run { cornerRadiusDp.toPx() }
Modifier.drawBehind {
val width = size.width
val height = size.height
drawLine(
color = color,
start = Offset(x = 0f, y = height),
end = Offset(x = 0f, y = cornerRadius),
strokeWidth = strokeWidthPx
)
// Top left arc
drawArc(
color = color,
startAngle = 180f,
sweepAngle = 90f,
useCenter = false,
topLeft = Offset.Zero,
size = Size(cornerRadius * 2, cornerRadius * 2),
style = Stroke(width = strokeWidthPx)
)
drawLine(
color = color,
start = Offset(x = cornerRadius, y = 0f),
end = Offset(x = width - cornerRadius, y = 0f),
strokeWidth = strokeWidthPx
)
// Top right arc
drawArc(
color = color,
startAngle = 270f,
sweepAngle = 90f,
useCenter = false,
topLeft = Offset(x = width - cornerRadius * 2, y = 0f),
size = Size(cornerRadius * 2, cornerRadius * 2),
style = Stroke(width = strokeWidthPx)
)
drawLine(
color = color,
start = Offset(x = width, y = height),
end = Offset(x = width, y = cornerRadius),
strokeWidth = strokeWidthPx
)
}
}
)
Run Code Online (Sandbox Code Playgroud)
用法
@Composable
private fun UShapeBorderSample() {
Card(
shape = RoundedCornerShape(
topEnd = 10.dp,
topStart = 10.dp,
bottomEnd = 0.dp,
bottomStart = 0.dp
),
modifier = Modifier
.semiBorder(1.dp, Color.Black, 10.dp)
) {
Box(
modifier = Modifier
.size(150.dp)
.background(Color.White),
contentAlignment = Alignment.Center
) {
Text("Hello World")
}
}
Spacer(modifier = Modifier.height(10.dp))
Card(
shape = RoundedCornerShape(
topEnd = 20.dp,
topStart = 20.dp,
bottomEnd = 0.dp,
bottomStart = 0.dp
),
modifier = Modifier
.semiBorder(1.dp, Color.Black, 20.dp)
) {
Box(
modifier = Modifier
.size(150.dp)
.background(Color.White),
contentAlignment = Alignment.Center
) {
Text("Hello World")
}
}
}
Run Code Online (Sandbox Code Playgroud)
您需要使用圆弧来创建圆角。创建形状时,您不会传递厚度,而是传递形状的半径。绘制边框时需要指定厚度。您绘制的是一个宽度为 1.dp 的矩形。
@Composable
private fun createShape(cornerRadius: Dp): Shape {
val density = LocalDensity.current
return GenericShape { size, _ ->
val width = size.width
val height = size.height
val cornerRadiusPx = density.run { cornerRadius.toPx() }
moveTo(0f, height)
// Vertical line on left size
lineTo(0f, cornerRadiusPx * 2)
arcTo(
rect = Rect(
offset = Offset.Zero,
size = Size(cornerRadiusPx * 2, cornerRadiusPx * 2)
),
startAngleDegrees = 180f,
sweepAngleDegrees = 90f,
forceMoveTo = false
)
lineTo(width - cornerRadiusPx * 2, 0f)
arcTo(
rect = Rect(
offset = Offset(width - cornerRadiusPx * 2, 0f),
size = Size(cornerRadiusPx * 2, cornerRadiusPx * 2)
),
startAngleDegrees = 270f,
sweepAngleDegrees = 90f,
forceMoveTo = false
)
// Vertical line on right size
lineTo(width, height)
}
}
Run Code Online (Sandbox Code Playgroud)
用法
@Composable
private fun UShapeBorderSample() {
Card(
shape = RoundedCornerShape(
topEnd = 10.dp,
topStart = 10.dp,
bottomEnd = 0.dp,
bottomStart = 0.dp
),
modifier = Modifier
.border(BorderStroke(width = 1.dp, color = Color.Black), createShape(10.dp))
) {
Box(modifier = Modifier
.size(200.dp)
.background(Color.White),
contentAlignment = Alignment.Center
) {
Text("Hello World")
}
}
}
Run Code Online (Sandbox Code Playgroud)
边框不尊重形状,因为它是一个绘图,但它Card
在Box
幕后使用形状,Modifier.clip()
其本身就是Modifier.graphicsLayer{clip}
在图层上应用操作。
您可以查看有关剪辑和边框的答案以了解差异。
归档时间: |
|
查看次数: |
3429 次 |
最近记录: |