【问题标题】:How to align centre text in other item of canvas in jetpack compose如何在 Jetpack Compose 的其他画布项目中对齐中心文本
【发布时间】:2023-02-26 09:40:00
【问题描述】:

我想在我的画布中对齐我的drawText 视图中心。我在 answer 的帮助下绘制了我的图像视图。现在我想在上面 drawText,但我的文本在我的视图中心。这有点复杂,但我会用图像向您展示。

@OptIn(ExperimentalTextApi::class)
@Composable
fun DrawProgressBar() {
    val rangeComposition = RangeComposition()
    val itemLst = rangeComposition.bpExplained
    val brush = Brush.horizontalGradient(listOf(Color.Red, Color.Blue))
    val progressBarPointer = rangeComposition.findReadingWithPointer(142, 90).second
    val textMeasurer = rememberTextMeasurer()
    textMeasurer.measure(text = AnnotatedString("Extremely high"))
    Canvas(
        modifier = Modifier
            .fillMaxWidth()
            .height(60.dp)
            .background(Color.White)
    ) {

        //triangle size

        val rectSize = Size(12.dp.toPx(), 9.dp.toPx())
        val strokeWidth = 8.dp
        val canvasWidth = size.width
        val canvasHeight = size.height
        val strokeWidthPx = density.run { strokeWidth.toPx() }
        val dashedPathEffect =
            PathEffect.dashPathEffect(floatArrayOf(canvasHeight / 38, canvasHeight / 38), 0f)
        val rect = Rect(Offset.Zero, rectSize)
        val trianglePath = Path().apply {
            moveTo(rect.bottomCenter.x, rect.bottomCenter.y)
            lineTo(rect.topRight.x, rect.topRight.y)
            lineTo(rect.topLeft.x, rect.topLeft.y)
            close()
        }
        val progressBarPointerInPixel = (progressBarPointer / 100f) * canvasWidth

        drawIntoCanvas { canvas ->
            // I want to fix this in centre of drawOutline
            drawText(
                textMeasurer = textMeasurer,
                text = "Extremely high",
                topLeft = Offset((progressBarPointerInPixel), 2.dp.toPx()),
                style = TextStyle(fontSize = 12.sp)
            )

            translate(progressBarPointerInPixel, 20.dp.toPx()) {
                canvas.drawOutline(
                    outline = Outline.Generic(trianglePath),
                    paint = Paint().apply {
                        color = Color.DarkGray
                        pathEffect = PathEffect.cornerPathEffect(rect.maxDimension / 3)
                    }
                )
            }

            drawLine(
                start = Offset(x = 0f, y = (canvasHeight / 4) * 3),
                end = Offset(x = canvasWidth, y = (canvasHeight / 4) * 3),
                color = Color.Gray,
                strokeWidth = strokeWidthPx,
                cap = StrokeCap.Round,
            )
            drawLine(
                color = Color.White,
                start = Offset(x = progressBarPointerInPixel, y = (canvasHeight / 4) * 3),
                end = Offset(x = progressBarPointerInPixel + strokeWidthPx / 2, y = (canvasHeight / 4) * 3),
                strokeWidth = strokeWidthPx,
            )
            drawLine(
                brush = brush,
                start = Offset(x = 0f, y = (canvasHeight / 4) * 3),
                end = Offset(x = progressBarPointerInPixel, y = (canvasHeight / 4) * 3),
                strokeWidth = strokeWidthPx,
                cap = StrokeCap.Round,
            )
            drawArc(
                topLeft = Offset(
                    x = progressBarPointerInPixel,
                    y = ((canvasHeight / 4) * 3) - strokeWidthPx / 2
                ),
                size = Size(strokeWidthPx, strokeWidthPx),
                color = Color.White,
                startAngle = -90f,
                sweepAngle = 180f,
                useCenter = true
            )
            itemLst.forEachIndexed { index, rangeItem ->
                val endPointInPixel = (rangeItem.endPoint / 100f) * canvasWidth
                if (index != itemLst.lastIndex) {
                    drawLine(
                        start = Offset(x = endPointInPixel, y = 30.dp.toPx()),
                        end = Offset(x = endPointInPixel, y = canvasHeight),
                        color = Color.Black,
                        strokeWidth = 1.2.dp.toPx(),
                        pathEffect = dashedPathEffect
                    )
                }
            }
        }
    }
}

实际产量

预期产出

当文本为“极高”时

当文本为“非常高”时

【问题讨论】:

    标签: android kotlin android-jetpack-compose android-jetpack-compose-canvas


    【解决方案1】:

    您对 Text 和三角形使用相同的水平偏移。
    Text 的右侧水平偏移量是三角形的中心 - textWidth/2。

    您可以使用:

        Canvas(modifier = Modifier.fillMaxSize()){
            
            val rectSize = Size (60f,60f)
            //... your code
    
            val triangleLeftOffset = 150f
    
            drawIntoCanvas { canvas ->
    
                translate (triangleLeftOffset,70f){
                    canvas.drawOutline(
                        outline = Outline.Generic(trianglePath),
                        //...
                    )
                }
            }
    
    
            val textLayoutResult: TextLayoutResult =
                textMeasurer.measure(
                    text = AnnotatedString("Extremely high"),
                    style = TextStyle(color = Color.Blue, fontSize = 20.sp)
                )
            val textSize = textLayoutResult.size
    
            val triangleCenterX = triangleLeftOffset + rectSize.width/2
    
            drawText(
                textLayoutResult = textLayoutResult,
                topLeft = Offset(
                    x  = triangleCenterX - textSize.width/2f,
                    y = 0f
                )
            )
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-01
      • 2021-10-29
      • 2021-11-15
      • 1970-01-01
      • 2022-10-25
      • 1970-01-01
      • 2023-02-13
      相关资源
      最近更新 更多