android 编写绘图文本离开屏幕

9rygscc1  于 2022-11-27  发布在  Android
关注(0)|答案(3)|浏览(174)

我正在使用下面的代码将文本绘制到画布上,但是您可以从照片中看到的文本将离开屏幕,而不是遵循我发布到画布的宽度参数,为什么会发生这种情况?
这似乎不会发生,如果我使用旧的android画布,可能的组成错误?

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
    }
}

siv3szwd

siv3szwd1#

1.4.0-alpha01TextStyle函数中添加了一个**DrawStyle**参数,用于绘制带轮廓的文本。
您可以使用类似于以下内容的内容:

val longText by remember {
    mutableStateOf("Choose the flash card which matches...!")
}

Box(
    modifier = Modifier
        .fillMaxWidth()
) {

    Canvas(modifier = Modifier.fillMaxSize()){
        //....
    }
    Text(
        text = longText,
        style = TextStyle.Default.copy(
            fontSize = 64.sp,
            drawStyle = Stroke(
                miter = 10f,
                width = 5f,
                join = StrokeJoin.Round
            )
        )
    )
}

zwghvu4y

zwghvu4y2#

通过将合成更新到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中,你可以把任何你想要的文本,甚至是emoji,输入到一个名为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)在画布中绘制文本drawText(textResult1)

you can create many variable also

然后在图面范围内测量文字。
这样,所有必要的操作,包括填充等,都是由api本身计算的,你只需要做你想做的事情。
您可以使用想要的样式制作textResults的多个副本,并调用不同的drawText来绘制具有不同样式的文本。
如果我的答案对你有帮助,请选择我的答案作为正确答案

qaxu7uf2

qaxu7uf23#

在jetpack compose中,DrawScope不必遵守你通过修改器设置的任何尺寸,除非你使用Modifier.clipModifier.clipToBounds。你可以画出画布边界之外的任何东西,这是你在画文本时的体验。
你可以有一个Composable与0宽度和0高度,但你可以绘制一个矩形与任何大小,你想要或偏移任何绘图Composable的边界,在默认情况下,他们不会削减你只是看不到他们,如果他们超出了屏幕边界。
比如说

Column {
    Canvas(
        modifier = Modifier
            .width(50.dp)
            .height(50.dp)
            .border(2.dp, Color.Red),
        onDraw = {
            drawCircle(
                color = Color.Green,
                center = Offset(500f, 300f),
                radius = 200f
            )
        }
    )

    Text("Hello World",
        modifier = Modifier.drawWithContent {
            drawContent()
            drawRect(Color.Cyan, style = Stroke(1.dp.toPx()))
            drawRoundRect(
                Color.Blue,
                topLeft = Offset(0f, 300f),
                size = Size(100f, 100f)
            )

        }
    )
}

“画布”在边界外绘制绿色圆形,而使用“文本”时,您将看到蓝色矩形也绘制在“文本”边界外。
记住这一点,你可以得出结论,它的大小只有做一些有意义的计算使用它,而不是限制文本或任何绘图。
您可以使用rememberTextMeasurer()来解决这个问题,以测量循环中的文本,其中的单词应该适合使用当前线宽与画布宽度的第一行。

相关问题