Abd*_*511 2 android kotlin android-jetpack-compose
我正在尝试使用 Compose 实现这个自定义形状
但由于某种原因,分隔符偏移圆用虚线绘制,这是代码
@Preview
@Composable
private fun ReceiptSeparator () {
Row(modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp) ,
verticalAlignment = Alignment.CenterVertically ,) {
Box(
modifier = Modifier
.requiredSize(50.dp)
.background(Color.White)
.offset(-40.dp)
.clip(CircleShape)
.border(BorderStroke(2.dp, Color.Gray))
){}
Box(
Modifier
.height(1.dp)
.requiredWidth(250.dp)
.weight(3f)
.background(Color.Gray, shape = DottedShape(step = 20.dp))
){}
Box(
modifier = Modifier
.offset(40.dp)
.clip(CircleShape)
.border(BorderStroke(2.dp, Color.Gray))
.background(Color.White)
.size(50.dp)
){}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么圆是用虚线绘制的以及如何正确地实现这个形状?
Phi*_*hov 12
您的圆绘制不正确,因为Modifier.border
默认情况下绘制一个矩形边框,然后您用Modifier.clip
. 相反,如果您需要将形状应用于边框,则需要将形状传递到Modifier.border
,如下所示:
.border(BorderStroke(2.dp, Color.Gray), shape = CircleShape)
Run Code Online (Sandbox Code Playgroud)
但这并不能解决你的问题。要像图像中所示正确绘制阴影,您需要将自定义形状应用到容器。
您可以使用Modifier.onGloballyPositioned
来获取截止位置:
var separatorOffsetY by remember { mutableStateOf<Float?>(null) }
val cornerRadius = 20.dp
Card(
shape = RoundedCutoutShape(separatorOffsetY, cornerRadius),
backgroundColor = Color.White,
modifier = Modifier.padding(10.dp)
) {
Column {
Box(modifier = Modifier.height(200.dp))
Box(
Modifier
.padding(horizontal = cornerRadius)
.height(1.dp)
.requiredWidth(250.dp)
// DottedShape is taken from this answer:
// /sf/answers/4815244381/
.background(Color.Gray, shape = DottedShape(step = 20.dp))
.onGloballyPositioned {
separatorOffsetY = it.boundsInParent().center.y
}
)
Box(modifier = Modifier.height(50.dp))
}
}
Run Code Online (Sandbox Code Playgroud)
使用此信息,您可以创建如下所示的形状:
class RoundedCutoutShape(
private val offsetY: Float?,
private val cornerRadiusDp: Dp,
) : Shape {
override fun createOutline(
size: Size,
layoutDirection: LayoutDirection,
density: Density,
) = Outline.Generic(run path@{
val cornerRadius = with(density) { cornerRadiusDp.toPx() }
val rect = Rect(Offset.Zero, size)
val mainPath = Path().apply {
addRoundRect(RoundRect(rect, CornerRadius(cornerRadius)))
}
if (offsetY == null) return@path mainPath
val cutoutPath = Path().apply {
val circleSize = Size(cornerRadius, cornerRadius) * 2f
val visiblePart = 0.25f
val leftOval = Rect(
offset = Offset(
x = 0 - circleSize.width * (1 - visiblePart),
y = offsetY - circleSize.height / 2
),
size = circleSize
)
val rightOval = Rect(
offset = Offset(
x = rect.width - circleSize.width * visiblePart,
y = offsetY - circleSize.height / 2
),
size = circleSize
)
addOval(leftOval)
addOval(rightOval)
}
return@path Path().apply {
op(mainPath, cutoutPath, PathOperation.Difference)
}
})
}
Run Code Online (Sandbox Code Playgroud)
结果:
归档时间: |
|
查看次数: |
7389 次 |
最近记录: |