kotlin 使用Canvas在屏幕外绘制文本

h9vpoimq  于 12个月前  发布在  Kotlin
关注(0)|答案(1)|浏览(194)

我想使用Canvas绘制一个文本,下面是我的代码:

val firstOffset = Offset(x = 0F, y = 0F)
val secondOffset = Offset(x = 0F, y = 1000F)
val thirdOffset = Offset(x = 0F, y = 1080F)
Canvas(
        modifier = Modifier.width(priceBarItemWidth)
            .fillMaxHeight()
            .pointerHoverIcon(
                PointerIcon(Cursor(N_RESIZE_CURSOR))
            )
    ) {
        drawText(
            textMeasurer = textMeasurer,
            text = "qwerty",
            topLeft = firstOffset,
            style = style
        )
    }

字符串
当我使用firstOffset文本去屏幕的左上角当我使用secondOffset文本去屏幕的左下角,当我使用thirdOffset我得到这个错误:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: 
maxHeight(-30) must be >= than minHeight(0)


我想把这个文本画出屏幕(我想用Canvas开发一个可滚动的列表,我知道有更好的方法来做到这一点),所以问题是我如何把文本画出屏幕,把滚动功能带到我的自定义列表!
原始代码如下:

val containerSize by service.containerSize.collectAsState()
Canvas(
        modifier = Modifier.width(priceBarItemWidth)
            .fillMaxHeight()
            .pointerHoverIcon(
                PointerIcon(Cursor(N_RESIZE_CURSOR))
            )
    ) {
        if (containerSize.height == 0) return@Canvas
        var currentHeight = 25 * (priceBarItemHeightInPx + 
            priceBarSpaceBetweenItemInPx)
        prices.forEachIndexed { index, fl ->
            drawText(
                textMeasurer = textMeasurer,
                text = fl.toString(),
                topLeft = Offset(x = 0F, y = 0F),
                style = style
            )
            currentHeight -= (priceBarItemHeightInPx + priceBarSpaceBetweenItemInPx)
        }
    }

vq8itlhq

vq8itlhq1#

这是由于drawText函数在这里的计算中传递了具有负高度的约束。
https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt;drc=4d53400eca9f3ac90c3a3f6cffcbc5bf492ec536;l=390
如果你没有设置drawTextsize参数,传递topLeft的值大于文本的高度,则会返回负的maxHeight,这是不允许的。传递小于minHeight的maxHeight也不允许用于约束。
您可以设置drawText函数的size参数,也可以使用DrawScope的translate函数作为

@Preview
@Composable
private fun CanvasTextSample() {

    val list = remember {
        listOf(
            "Hello",
            "World",
            "Text1",
            "Text2",
            "Text3",
            "Text4",
        )
    }

    Column(
        modifier = Modifier.padding(16.dp).fillMaxSize().padding(top = 60.dp)
    ) {

        val textMeasurer = rememberTextMeasurer()

        var offset by remember {
            mutableStateOf(0f)
        }

        Canvas(
            modifier = Modifier
                .pointerInput(Unit) {
                    detectDragGestures { change, dragAmount ->
                        offset += dragAmount.y
                    }
                }
                .fillMaxWidth()
                .aspectRatio(1f)
                .border(1.dp, Color.Red)
        ) {

            list.fastForEachIndexed { index, text ->
                translate(
                    left = 100f,
                    top = offset + index * 20.dp.toPx()
                ) {
                    drawText(
                        textMeasurer = textMeasurer,
                        text = text,
                    )
                }
            }
        }
    }
}

字符串
如果您希望将文本水平居中放置在画布内,请使用textMeasurer.measure()获取TextLayoutResult,并使用返回的大小和画布大小将文本居中。

相关问题