【问题标题】:Compose drawText going off screen撰写 drawText 离开屏幕
【发布时间】:2022-11-12 17:33:45
【问题描述】:

我正在使用以下代码将文本绘制到 Canvas 上,但是您从照片中看到的文本正在离开屏幕,而不是遵循我向 Canvas 发出的宽度参数,为什么会发生这种情况?

如果我使用较旧的 android 画布,这似乎不会发生,可能是 compose 错误?

 Box(
    modifier = Modifier
        .fillMaxWidth()
) {
    Canvas(
        modifier = Modifier.width(500.dp),
        onDraw = {
            drawIntoCanvas {
                it.nativeCanvas.drawText(
                    text,
                    0f,
                    120.dp.toPx(),
                    textPaintStroke(context = context)
                )
                it.nativeCanvas.drawText(
                    text,
                    0f,
                    120.dp.toPx(),
                    textPaint(context = context)
                )
            }
        }
    )
}

fun textPaintStroke(
    context: Context
): NativePaint {
    val customTypeface = ResourcesCompat.getFont(context, R.font.baloo2_semi_bold)

    return Paint().asFrameworkPaint().apply {
        isAntiAlias = true
        style = android.graphics.Paint.Style.STROKE
        textSize = 64f
        color = android.graphics.Color.BLACK
        strokeWidth = 12f
        strokeMiter= 10f
        strokeJoin = android.graphics.Paint.Join.ROUND
        typeface = customTypeface
    }
}

fun textPaint(
    context: Context
): NativePaint {
    val customTypeface = ResourcesCompat.getFont(context, R.font.baloo2_semi_bold)

    return Paint().asFrameworkPaint().apply {
        isAntiAlias = true
        style = android.graphics.Paint.Style.FILL
        textSize = 64f
        color = android.graphics.Color.WHITE
        typeface = customTypeface
    }
}

【问题讨论】:

    标签: android android-jetpack-compose


    【解决方案1】:

    您可以通过将 Compose 更新到 1.3.0 版来使用以下功能:

    import androidx.compose.foundation.Canvas
    import androidx.compose.foundation.background
    import androidx.compose.foundation.layout.Box
    import androidx.compose.foundation.layout.fillMaxSize
    import androidx.compose.foundation.layout.width
    import androidx.compose.runtime.Composable
    import androidx.compose.runtime.getValue
    import androidx.compose.runtime.mutableStateOf
    import androidx.compose.runtime.remember
    import androidx.compose.ui.Modifier
    import androidx.compose.ui.graphics.Color
    import androidx.compose.ui.text.AnnotatedString
    import androidx.compose.ui.text.ExperimentalTextApi
    import androidx.compose.ui.text.SpanStyle
    import androidx.compose.ui.text.drawText
    import androidx.compose.ui.text.rememberTextMeasurer
    import androidx.compose.ui.unit.dp
    import androidx.compose.ui.unit.sp
    
    @OptIn(ExperimentalTextApi::class)
    @Composable
    fun Test() {
        val text by remember {
            mutableStateOf("Choose the flash with matechest!")
        }
        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(Color.Green)
        ) {
            val textMeasurer = rememberTextMeasurer()
            Canvas(
                modifier = Modifier.width(10.dp),
                onDraw = {
                    val textResult = textMeasurer.measure(
                        AnnotatedString(
                            text, spanStyle = SpanStyle(
                                fontSize = 24.sp
                            )
                        )
                    )
                    drawText(textResult)
                }
            )
        }
    }
    

    通过这种方式,您可以设置文本样式并...

    虽然这个功能现在是作为ExperimentalTextApi发布的,但是根据我一年使用compose的经验,我向你保证不会有问题。

    更多信息:如您所知,在 1.3.0 版之前,无法通过撰写 API 在画布上绘制文本。

    此功能在新版本中可用。 在新的 API 中,您可以将所需的任何文本(甚至表情符号)提供给名为 rememberTextMeasurer() 的组合。

    第一步:

       val textMeasurer = rememberTextMeasurer()
    

    第二步:创建新变量并调用 measure 方法进行画布计算,以演示绘制什么、在哪里绘制等。

    val textResult1 = textMeasurer.measure(
                        AnnotatedString(
                            text, spanStyle = SpanStyle(
                                fontSize = 24.sp,
                                shadow = Shadow(color = Color.Black),
                                color = Color.White
                            )
                        )
                    )
    

    第三步: 调用 drawText(textResult1) 在画布中绘制文本 绘制文本(文本结果 1)

    you can create many variable also
    

    然后在绘图范围内测量文本。

    有了这个,所有必要的操作,包括padding等,都由api自己计算,你只参与你想要的。

    您可以使用您想要的样式制作多个 textResults 副本,并调用不同的 drawTexts 以使用不同的样式绘制您想要的文本。

    我希望它对你有用 如果我的回答对您有帮助,请选择我的回答为正确答案

    【讨论】:

    • 您能否尝试提供更多有关此操作的背景信息
    • @alfietap 我为我的答案添加了更多解释
    • 不幸的是,这会导致文本离开屏幕时出现相同的问题。它也失去了为文本添加轮廓的能力,阴影不太一样
    猜你喜欢
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    • 2020-10-31
    • 2017-10-23
    • 2020-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多