Android Jetpack 在 Box 中组合部分边框
Android Jetpack compose partial border in Box
我正在尝试在 jetpack compose 中准备一个在盒子的一侧有部分边框的设计。这是我现在拥有的 UI,
背景目前是纯色,但将替换为图片。我想打破左下角的边框并添加一些类似于下面屏幕截图的文本,同时保持背景不变。
这是我的代码:
Box(modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()) {
Box(modifier = Modifier.fillMaxHeight().fillMaxWidth().background(Color(0xFF37C7D7).copy(alpha = 0.6f)))
Box(modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.background(Color.Transparent)
.padding(20.dp,30.dp)
.border(width = 0.8.dp, color = Color.White.copy(alpha = 0.5f), shape=RoundedCornerShape(32.dp))
)
Box(modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.background(Color.Transparent)
.padding(28.dp,38.dp)
.border(width = 0.8.dp, color = Color.White.copy(alpha = 0.5f), shape=RoundedCornerShape(28.dp))
)
Column(modifier = Modifier.statusBarsPadding()
.fillMaxWidth()
.fillMaxHeight().padding(20.dp,40.dp),
verticalArrangement = Arrangement.Bottom) {
Text(text = "this is Test",modifier = Modifier.padding(0.dp,30.dp))
}
}
您可以使用 Modifier.drawWithContent
and DrawScope.clipRect
阻止部分视图被绘制。使用此方法,您可以创建以下修饰符:
fun Modifier.drawWithoutRect(rect: Rect?) =
drawWithContent {
if (rect != null) {
clipRect(
left = rect.left,
top = rect.top,
right = rect.right,
bottom = rect.bottom,
clipOp = ClipOp.Difference,
) {
this@drawWithContent.drawContent()
}
} else {
drawContent()
}
}
这样使用:
Box(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
) {
Image(
painterResource(id = R.drawable.my_image),
contentDescription = null,
contentScale = ContentScale.FillBounds,
modifier = Modifier.fillMaxSize()
)
var textCoordinates by remember { mutableStateOf<Rect?>(null) }
Box(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.background(Color(0xFF37C7D7).copy(alpha = 0.6f))
)
Box(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.drawWithoutRect(textCoordinates)
.padding(20.dp, 30.dp)
.border(
width = 0.8.dp,
color = Color.White.copy(alpha = 0.5f),
shape = RoundedCornerShape(32.dp)
)
)
Box(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.drawWithoutRect(textCoordinates)
.padding(28.dp, 38.dp)
.border(
width = 0.8.dp,
color = Color.White.copy(alpha = 0.5f),
shape = RoundedCornerShape(28.dp)
)
)
Column(
verticalArrangement = Arrangement.Bottom,
modifier = Modifier
.statusBarsPadding()
.padding(20.dp, 40.dp)
.onGloballyPositioned {
textCoordinates = it.boundsInParent()
}
.align(Alignment.BottomStart)
) {
Text(text = "this is Test", modifier = Modifier.padding(0.dp, 30.dp))
}
}
结果:
我正在尝试在 jetpack compose 中准备一个在盒子的一侧有部分边框的设计。这是我现在拥有的 UI,
背景目前是纯色,但将替换为图片。我想打破左下角的边框并添加一些类似于下面屏幕截图的文本,同时保持背景不变。
这是我的代码:
Box(modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()) {
Box(modifier = Modifier.fillMaxHeight().fillMaxWidth().background(Color(0xFF37C7D7).copy(alpha = 0.6f)))
Box(modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.background(Color.Transparent)
.padding(20.dp,30.dp)
.border(width = 0.8.dp, color = Color.White.copy(alpha = 0.5f), shape=RoundedCornerShape(32.dp))
)
Box(modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.background(Color.Transparent)
.padding(28.dp,38.dp)
.border(width = 0.8.dp, color = Color.White.copy(alpha = 0.5f), shape=RoundedCornerShape(28.dp))
)
Column(modifier = Modifier.statusBarsPadding()
.fillMaxWidth()
.fillMaxHeight().padding(20.dp,40.dp),
verticalArrangement = Arrangement.Bottom) {
Text(text = "this is Test",modifier = Modifier.padding(0.dp,30.dp))
}
}
您可以使用 Modifier.drawWithContent
and DrawScope.clipRect
阻止部分视图被绘制。使用此方法,您可以创建以下修饰符:
fun Modifier.drawWithoutRect(rect: Rect?) =
drawWithContent {
if (rect != null) {
clipRect(
left = rect.left,
top = rect.top,
right = rect.right,
bottom = rect.bottom,
clipOp = ClipOp.Difference,
) {
this@drawWithContent.drawContent()
}
} else {
drawContent()
}
}
这样使用:
Box(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
) {
Image(
painterResource(id = R.drawable.my_image),
contentDescription = null,
contentScale = ContentScale.FillBounds,
modifier = Modifier.fillMaxSize()
)
var textCoordinates by remember { mutableStateOf<Rect?>(null) }
Box(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.background(Color(0xFF37C7D7).copy(alpha = 0.6f))
)
Box(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.drawWithoutRect(textCoordinates)
.padding(20.dp, 30.dp)
.border(
width = 0.8.dp,
color = Color.White.copy(alpha = 0.5f),
shape = RoundedCornerShape(32.dp)
)
)
Box(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
.drawWithoutRect(textCoordinates)
.padding(28.dp, 38.dp)
.border(
width = 0.8.dp,
color = Color.White.copy(alpha = 0.5f),
shape = RoundedCornerShape(28.dp)
)
)
Column(
verticalArrangement = Arrangement.Bottom,
modifier = Modifier
.statusBarsPadding()
.padding(20.dp, 40.dp)
.onGloballyPositioned {
textCoordinates = it.boundsInParent()
}
.align(Alignment.BottomStart)
) {
Text(text = "this is Test", modifier = Modifier.padding(0.dp, 30.dp))
}
}
结果: