I am trying to prepare a design in jetpack compose with a partial border on one side of the box. Here is the UI I have right now,
The background is a solid color as of now but will be replaced with a image. I want to break border on bottom left of and add some text similar to the screenshot below while keeping the background as it is.
Here is my code:
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))
}
}
CodePudding user response:
You can prevent part of the view from being drawn with Modifier.drawWithContent and clipRect. Using this method, you can create the following modifier:
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()
}
}
Use it like this:
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))
}
}
Result: