我正在尝试在 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
),
如何实现? 感谢任何帮助。
注意:我为文本应用的浅红色背景只是为了可视化用于文本的底层矩形。另外,我在圆心画了一个点,以便更清楚。
您可以获得 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
)
}
}
}