You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Jetpack Compose 如何为Box添加带文本打断的局部边框效果

要实现带缺口的局部边框效果,因为后续背景要替换为图片,不能用色块遮挡边框伪造缺口,所以直接自定义绘制边框即可,具体实现如下:

步骤1:自定义带缺口的圆角边框修饰符

我们通过drawBehind手动绘制边框路径,在左下角预留对应文本宽度的缺口:

fun Modifier.notchedRoundedBorder(
    borderWidth: Dp,
    borderColor: Color,
    cornerRadius: Dp,
    notchWidth: Dp,
    notchPadding: Dp = 8.dp // 缺口与文本的左右留白
) = this.then(
    Modifier.drawBehind {
        val borderPx = borderWidth.toPx()
        val cornerPx = cornerRadius.toPx()
        val notchTotalWidth = notchWidth.toPx() + notchPadding.toPx() * 2

        val borderPath = Path().apply {
            // 从左下角缺口右端点开始绘制
            moveTo(notchTotalWidth, size.height - cornerPx)
            // 左下角圆角
            arcTo(
                rect = Rect(0f, size.height - cornerPx * 2, cornerPx * 2, size.height),
                startAngleDegrees = 90f,
                sweepAngleDegrees = 90f,
                forceMoveTo = false
            )
            // 底部边框到右下角圆角
            lineTo(size.width - cornerPx, size.height)
            // 右下角圆角
            arcTo(
                rect = Rect(size.width - cornerPx * 2, size.height - cornerPx * 2, size.width, size.height),
                startAngleDegrees = 0f,
                sweepAngleDegrees = -90f,
                forceMoveTo = false
            )
            // 右侧边框到右上角圆角
            lineTo(size.width, cornerPx)
            // 右上角圆角
            arcTo(
                rect = Rect(size.width - cornerPx * 2, 0f, size.width, cornerPx * 2),
                startAngleDegrees = 270f,
                sweepAngleDegrees = -90f,
                forceMoveTo = false
            )
            // 顶部边框到左上角圆角
            lineTo(cornerPx, 0f)
            // 左上角圆角
            arcTo(
                rect = Rect(0f, 0f, cornerPx * 2, cornerPx * 2),
                startAngleDegrees = 180f,
                sweepAngleDegrees = -90f,
                forceMoveTo = false
            )
            // 左侧边框到缺口左端点停止,留空缺口
            lineTo(0f, size.height - cornerPx * 2)
        }

        drawPath(
            path = borderPath,
            color = borderColor,
            style = Stroke(width = borderPx)
        )
    }
)

步骤2:替换原有布局的border修饰符

先测量文本宽度用来匹配缺口大小,再替换原有边框逻辑:

@Composable
fun NotchedBorderScreen() {
    val displayText = "this is Test"
    // 测量文本宽度,自动适配缺口大小
    val textPaint = remember { Paint().apply { textSize = 14.sp.toPx() } }
    val textWidth = textPaint.measureText(displayText).toDp()

    Box(
        modifier = Modifier
            .fillMaxWidth()
            .fillMaxHeight()
    ) {
        // 背景层,后续直接替换为Image组件即可
        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(Color(0xFF37C7D7).copy(alpha = 0.6f))
        )
        // 外层带缺口边框
        Box(
            modifier = Modifier
                .fillMaxSize()
                .padding(20.dp, 30.dp)
                .notchedRoundedBorder(
                    borderWidth = 0.8.dp,
                    borderColor = Color.White.copy(alpha = 0.5f),
                    cornerRadius = 32.dp,
                    notchWidth = textWidth
                )
        )
        // 内层带缺口边框
        Box(
            modifier = Modifier
                .fillMaxSize()
                .padding(28.dp, 38.dp)
                .notchedRoundedBorder(
                    borderWidth = 0.8.dp,
                    borderColor = Color.White.copy(alpha = 0.5f),
                    cornerRadius = 28.dp,
                    notchWidth = textWidth
                )
        )
        // 文本层,放在缺口位置
        Column(
            modifier = Modifier
                .statusBarsPadding()
                .fillMaxSize()
                .padding(20.dp, 40.dp),
            verticalArrangement = Arrangement.Bottom
        ) {
            Text(
                text = displayText,
                modifier = Modifier.padding(8.dp, 30.dp),
                color = Color.White,
                fontSize = 14.sp
            )
        }
    }
}

该方案完全没有用背景遮挡边框,后续替换背景为图片不会有任何适配问题,所有圆角、边框样式都和你原有代码保持一致,仅移除了左下角对应文本长度的边框段。如果需要调整缺口位置或者大小,直接修改notchedRoundedBorder的参数即可。

内容的提问来源于stack exchange,提问作者Ankit Shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 00:36:00