我正在try 在Jetpack Compose中画一个圆圈内的文本.

我画了一个圆,圆心是画布的中心.

现在我想要在圆的中心精确地绘制文本.

Jetpack Compose中canvas中的drawText函数有topLeft参数,该参数需要保存文本的矩形左上角的Offset.我知道我不能把圆的中心作为topLeft的偏移量,如果我这样做了,结果会是这样的,这不是我想要的.

trying to draw the text at the center of the circle

我希望文本准确地画在圆圈的中心.

以下是代码:

Box(
    modifier = Modifier
        .fillMaxSize()
        .background(Color.Green.copy(alpha = 0.2f))
        .padding(36.dp),
    contentAlignment = Alignment.Center
) {
    val textMeasurer = rememberTextMeasurer()
    val textToDraw = "A"
    Canvas(modifier = Modifier.fillMaxSize()) {
        drawCircle(
            center = Offset(
                x = center.x,
                y = center.y
            ),
            radius = 350f,
            color = Color.Blue,
            style = Stroke(
                width = 8f
            )
        )

        drawText(
            textMeasurer = textMeasurer,
            text = textToDraw,
            style = TextStyle(
                fontSize = 150.sp,
                color = Color.Black,
                background = Color.Red.copy(alpha = 0.2f)
            ),
            topLeft = Offset(
                x = center.x,
                y = center.y
            )
        )
        drawPoints(
            points = listOf(Offset(center.x, center.y)),
            pointMode = PointMode.Points,
            cap = StrokeCap.Round,
            color = Color.Red,
            strokeWidth = 25f
        )
    }
}

我可以像这样手动调整偏移量以使其工作,但这不是最佳的和自动的.

topLeft = Offset(
    x = center.x - 125,
    y = center.y - 270
),

text centered in the circle

如何才能做到这一点? 感谢任何人的帮助.

注意:我为文本应用的淡红色背景只是为了使文本所使用的底层矩形可视化.我还在圆的中心画了一个点,以便更清楚地说明.

推荐答案

您可以获取TextLayoutResult,它返回包含文本的矩形的大小.安迪,通过将宽度的一半向左偏移,高度的一半向上偏移,可以使文本在画布内居中.

enter image description here

val textMeasurer = rememberTextMeasurer()

val textToDraw = "A"

val style = TextStyle(
    fontSize = 150.sp,
    color = Color.Black,
    background = Color.Red.copy(alpha = 0.2f)
)
// Keys are to demonstrate that you can re-calculate block inside
// when any of them change. Otherwise remember results on each recomposition
val textLayoutResult = remember(textToDraw, style) {
    textMeasurer.measure(textToDraw, style)
}

完整样品

@Preview
@Composable
private fun DrawTextAtCenterSample() {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.Green.copy(alpha = 0.2f))
            .padding(36.dp),
        contentAlignment = Alignment.Center
    ) {
        val textMeasurer = rememberTextMeasurer()

        val textToDraw = "A"

        val style = TextStyle(
            fontSize = 150.sp,
            color = Color.Black,
            background = Color.Red.copy(alpha = 0.2f)
        )

        val textLayoutResult = remember(textToDraw) {
            textMeasurer.measure(textToDraw, style)
        }

        Canvas(modifier = Modifier.fillMaxSize()) {
            drawCircle(
                center = Offset(
                    x = center.x,
                    y = center.y
                ),
                radius = 350f,
                color = Color.Blue,
                style = Stroke(
                    width = 8f
                )
            )


            drawText(
                textMeasurer = textMeasurer,
                text = textToDraw,
                style = style,
                topLeft = Offset(
                    x = center.x - textLayoutResult.size.width / 2,
                    y = center.y - textLayoutResult.size.height / 2,
                )
            )
            drawPoints(
                points = listOf(Offset(center.x, center.y)),
                pointMode = PointMode.Points,
                cap = StrokeCap.Round,
                color = Color.Red,
                strokeWidth = 25f
            )
        }
    }
}

Android相关问答推荐

以编程方式更改Android应用程序上的文件许可

如何使用视图模型触发可变状态?

原始mp3文件不显示与proguard

如何在初始合成期间在可组合函数中调用/获取远程API中的数据[防止无限重组]

在Jetpack Compose中实现焦点突出的最佳方式?

我无法在底部导航栏中正确导航-Android底部导航视图

可以';t将数据插入房间数据库

如何从包装在泛型中的 retrofit 调用中检索密钥?

为卡片的上半部分添加一个边框,用圆角半径组合

在事件中使用 Context/Toast 时不需要的重组 - Jetpack Compose

react 从输入中找到路径'lib/arm64-v8a/libfbjni.so'的本机2个文件

Kotlin:如何在另一个变量的名称中插入一个变量的值

在开发过程中我应该把 mp4 文件放在哪里?

如何从 Jetpack Compose 中的 Radio 组中获取价值

Google Play 控制台您的应用是否使用广告 ID?

如何使用 Kotlin 在 Android Wear(Galaxy watch 4)中继续在后台运行应用程序

可扩展性 Qt 5.15 Android

如何在 kotlin 的 android room DB 中设置一对多关系

Jetpack Compose Tapjacking:过滤对模糊 UI 的touch

如何满足设备内框架的无效 Wear OS 屏幕截图Wear OS 表盘策略违规?