enter image description here

我对Android Compose比较陌生,作为一个项目,我正在try 设计一个条形图.收集各种示例,我现在正try 在可用DrawScope合成的画布中设计轴.一旦我画了线,我的下一个任务就是在画布的右侧创建y轴的标签.但如图所示,在try 将文本与y轴上的适当分隔线对齐时,我遇到了一个障碍,即最终的DraText在画布底部.然而,它可以画在画布的顶部.我不知道为什么,但这可能是我写下面的Composable的方式的一个缺陷.

    @OptIn(ExperimentalTextApi::class)
    @Composable
    fun BarGraphAxes(modifier: Modifier,
                     verticalLines: Int,
                     horizontalLines : Int) {
        val barAxisColor = colorResource(id = R.color.grey)
        val textColor = colorResource(id = R.color.textprimary)
        val configuration = LocalConfiguration.current

        Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Top) {
            Box(modifier = Modifier
                .width(configuration.screenWidthDp.dp)
                .height(300.dp)
                .padding(start = 30.dp, top = 20.dp)
            ) {
                val textMeasurer = rememberTextMeasurer()
                Canvas(modifier = Modifier.fillMaxSize()) {
                    val barWidthPx =
                        1.dp.toPx() //calculate in DP before converting to Px is the Compose preferred way to draw
                    val yAxisBottomExtraOffset = 20.dp.toPx()
                    val dashPathEffect =
                        PathEffect.dashPathEffect(
                            intervals = floatArrayOf(10f, 10f),
                            phase = 0f
                        )
                    val myWidth = (size.width.toDp() - 50.dp).toPx()
                    val topPaddingForAxes = 15

                    //draw X-Axis
                    drawLine(
                        color = barAxisColor,
                        start = Offset(0f, size.height),
                        end = Offset(myWidth, size.height),
                        strokeWidth = barWidthPx,
                    )

                    //draw Y-Axis right hand
                    drawLine(
                        color = barAxisColor,
                        start = Offset(myWidth, 0f),
                        end = Offset(myWidth, size.height + yAxisBottomExtraOffset),
                        strokeWidth = barWidthPx,
                        pathEffect = dashPathEffect
                    )

                    //draw Y-Axis left hand
                    drawLine(
                        color = barAxisColor,
                        start = Offset(0f, 0f),
                        end = Offset(0f, size.height + yAxisBottomExtraOffset),
                        strokeWidth = barWidthPx,
                        pathEffect = dashPathEffect
                    )

                    //draw X-Axis top
                    drawLine(
                        color = barAxisColor,
                        start = Offset(0f, 0f),
                        end = Offset(myWidth, 0f),
                        strokeWidth = barWidthPx,
                    )

                    val horizontalSize = size.height / (horizontalLines + 1)
                    val verticalSize = myWidth / (verticalLines + 1) //distance between the axes

                    //Note, this is not where the final drawText will be at, just experimenting with static positioning.
                    drawText(textMeasurer, text = "Label", style = TextStyle(fontSize = 12.sp, color = textColor), overflow = TextOverflow.Ellipsis, topLeft = Offset(myWidth, 0f - 20f))
                    drawText(textMeasurer, text = "Label", style = TextStyle(fontSize = 12.sp, color = textColor), overflow = TextOverflow.Ellipsis, topLeft = Offset(myWidth, horizontalSize - 20f))
                    drawText(textMeasurer, text = "Label", style = TextStyle(fontSize = 12.sp, color = textColor), overflow = TextOverflow.Ellipsis, topLeft = Offset(myWidth, (horizontalSize * 2) - 20f))
                    drawText(textMeasurer, text = "Label", style = TextStyle(fontSize = 12.sp, color = textColor), overflow = TextOverflow.Ellipsis, topLeft = Offset(myWidth, (horizontalSize * 3) - 20f))


                    //draw the dividing vertical axes
                    repeat(verticalLines) { i ->
                        val startXCoordinate = verticalSize * (i + 1) //start at 0
                        drawLine(
                            color = barAxisColor,
                            start = Offset(startXCoordinate, 0f),
                            end = Offset(
                                startXCoordinate,
                                size.height + yAxisBottomExtraOffset
                            ),
                            strokeWidth = barWidthPx,
                            pathEffect = dashPathEffect
                        )
                    }

                    //draw the dividing horizontal axes
                    repeat(horizontalLines) { i ->
                        val startYCoordinate = horizontalSize * (i + 1)
                        drawLine(
                            color = barAxisColor,
                            start = Offset(0f, startYCoordinate),
                            end = Offset(myWidth, startYCoordinate),
                            strokeWidth = barWidthPx
                        )
                    }
                }
            }
        }
    }

如果有人能给我指明正确的方向,解释为什么draText在底部,而不是在顶部,我将不胜感激.

推荐答案

可能有一个以TextMeasurer为参数的重载函数的错误.如果您使用

val textMeasurer = rememberTextMeasurer()
val result = remember {
    textMeasurer.measure(
        text="Label",
        style = TextStyle(fontSize = 12.sp, color = textColor),
        overflow = TextOverflow.Ellipsis
    )
}

并用它作画

drawText(
    textLayoutResult = result,
    topLeft = Offset(myWidth, (horizontalSize * 3) - 20f)
)

它工作得很好.你应该能够从画布中画出任何东西,除非画布或它的任何父画布被剪裁.

Android相关问答推荐

Android Compose Lazy柱形实时UI更改

如何在"不同活动"中添加不同按钮?

在Kotlin Jetpack Compose中点击按钮后启动另一个Android应用程序

Jetpack编写使用自定义主题覆盖库中主题部分

Android Studio SQLite 错误:列不正确(没有这样的列:_id)

从不可组合回调打开可组合屏幕

同样的参数值下,为什么requiredSizeIn不等于requiredWidthIn + requiredHeightIn?

SQLite Kotlin 问题 - 没有数据库

在 Android Studio 中获取更新版本的 Picasso 库的错误警告消息

Jetpack Compose:如何绘制异形边框?

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

安卓模拟器打不开

为什么我的应用程序使用这些信息?

compose 导航参数字符串包含花括号?

如果 auth 失败,如何显示 toast jetpack compose firebase if else @Composable 调用只能在 @Composable 函数的上下文中发生

Jetpack Compose - 每次点击按钮都不起作用

无法 HEAD 'https://jcenter.bintray.com/com/facebook/react/react-native/maven-metadata.xml'

您如何衡量条形图的 4 个类别?

Android:为什么 ICICI iMobile Pay 应用程序在我的应用程序中显示root/jailbroken设备?

在 Room 中创建一对多关系时,@Relation 类是什么意思?