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

Jetpack Compose中Canvas内drawText与图形居中对齐问题

Jetpack Compose Canvas 文本与图形水平居中对齐方案

核心思路

drawText 默认以文本左上角为绘制原点,要实现文本与下方三角形水平居中,需先测量文本宽度,再让文本的水平中心与三角形的水平中心重合。

具体实现步骤

  1. 获取文本测量器:通过 rememberTextMeasurer() 创建可复用的文本测量实例,用于计算文本尺寸。
  2. 测量文本尺寸:调用 textMeasurer.measure() 方法,传入文本内容和对应样式,获取文本的实际宽度。
  3. 计算居中偏移:根据三角形的中心X坐标,倒推文本的绘制X坐标(三角形中心X - 文本宽度/2),确保两者水平中心对齐。
  4. 绘制文本与图形:使用计算后的坐标绘制文本,完成居中对齐。

完整代码示例

@Composable
fun CenteredTextTriangle() {
    val textMeasurer = rememberTextMeasurer()
    val labelList = listOf("Extremely high", "Very high")
    val triangleSize = 40.dp
    val triangleSizePx = with(LocalDensity.current) { triangleSize.toPx() }

    Canvas(modifier = Modifier.fillMaxWidth().height(200.dp)) {
        val canvasWidth = size.width
        labelList.forEachIndexed { index, label ->
            // 计算三角形的水平中心坐标(此处均匀分布,可替换为固定值)
            val triangleCenterX = canvasWidth * (index + 1) / (labelList.size + 1)
            val triangleTopY = 80.dp.toPx() + index * 60.dp.toPx()

            // 绘制三角形(以triangleCenterX为水平中心)
            drawPath(
                path = Path().apply {
                    moveTo(triangleCenterX, triangleTopY)
                    lineTo(triangleCenterX - triangleSizePx/2, triangleTopY + triangleSizePx)
                    lineTo(triangleCenterX + triangleSizePx/2, triangleTopY + triangleSizePx)
                    close()
                },
                color = Color.Blue
            )

            // 测量当前文本的实际宽度
            val textLayout = textMeasurer.measure(
                text = AnnotatedString(label),
                style = TextStyle(fontSize = 14.sp, color = Color.Black)
            )
            val textWidth = textLayout.size.width

            // 计算文本绘制的X坐标,确保与三角形水平居中
            val textX = triangleCenterX - textWidth / 2f
            val textY = triangleTopY - 20.dp.toPx() // 文本位于三角形上方

            // 绘制居中对齐的文本
            drawText(
                textMeasurer = textMeasurer,
                text = label,
                topLeft = Offset(textX, textY),
                style = TextStyle(fontSize = 14.sp, color = Color.Black)
            )
        }
    }
}

关键注意事项

  • 测量文本时的 TextStyle 必须与绘制时完全一致,否则会出现测量宽度与实际绘制宽度不符的偏差。
  • 如果三角形位置固定,直接将 triangleCenterX 替换为固定坐标即可,无需动态计算。

内容的提问来源于stack exchange,提问作者Compose Learner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:42:43