Android Jetpack Compose中Box控件如何实现局部边框?

6
我正在尝试使用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))
    }
}
1个回答

10
你可以使用Modifier.drawWithContentDrawScope.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))
    }
}

结果:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接