如何在 Jetpack compose 中将文本绘制在另一个对象的中心?

问题描述 投票:0回答:1

我正在尝试在 Jetpack Compose 中的圆圈内绘制文本。

我画了圆,圆心是画布的中心。

现在我想在圆心精确地绘制文本。

Jetpack compose 中

drawText
内的
canvas
函数具有
topLeft
参数,该参数期望包含文本的矩形左上角的
Offset
。我知道我不能通过圆心作为
topLeft
偏移量,如果我这样做,结果将是这样的,这不是我想要的。

我想让文字精确地绘制在圆的中心。

代码如下:

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
),

如何实现? 感谢任何帮助。

注意:我为文本应用的浅红色背景只是为了可视化用于文本的底层矩形。另外,我在圆心画了一个点,以便更清楚。

android android-jetpack-compose android-canvas drawtext android-jetpack-compose-canvas
1个回答
0
投票

您可以获得 TextLayoutResult,它返回包含文本的矩形的大小。 Andy 通过将宽度的一半偏移到左侧和高度的一半偏移到顶部,您可以在 Canvas 中将文本居中。

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
            )
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.