簡體   English   中英

撰寫離開屏幕的 drawText

[英]Compose drawText going off screen

我正在使用以下代碼在 Canvas 上繪制文本,但是您從照片中看到的文本從屏幕上消失了,而不是遵循我向 Canvas 發出的寬度參數,為什么會這樣?

如果我使用較舊的 android canvas,這似乎不會發生,可能是 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
    }
}

在此處輸入圖像描述

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

在此處輸入圖像描述

您可以通過將 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)
            }
        )
    }
}

通過這種方式,您可以設置文本樣式並...

雖然這個function現在是作為ExperimentalTextApi發布的,但是根據我一年的compose使用經驗,保證不會有問題。

更多信息:如您所知,在 1.3.0 版本之前,無法通過 compose API 在 canvas 上繪制文本。

此功能在新版本中可用。 在新的 API 中,您可以將任何想要的文本(甚至是表情符號)提供給名為 rememberTextMeasurer() 的組合。

第一步:

   val textMeasurer = rememberTextMeasurer()

第二步:新建變量,調用measure方法進行canvas計算,演示畫什么,畫哪里等。

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

第三步:調用drawText(textResult1)在canvas繪制文本drawText(textResult1)

you can create many variable also

然后你在你的繪圖 scope 中測量你的文字。

有了這個,所有必要的操作,包括填充等,都由api自己計算,你只參與你想要的。

你可以用你想要的 styles 復制幾份 textResults 並調用不同的 drawTexts 用不同的 styles 繪制你想要的文本。

希望對你有用 如果我的回答對你有幫助,請選擇我的答案作為正確答案

在 jetpack compose 中, DrawScope不必遵守您通過 Modifier 設置的任何維度,除非您使用Modifier.clipModifier.clipToBounds 您可以在 canvas 范圍內繪制任何內容,這就是您在繪制文本時的體驗。

您可以擁有一個寬度為 0 高度為 0 的Composable ,但您可以繪制一個任意大小的矩形,或者將任何繪圖偏移到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)
            )

        }
    )
}

在此處輸入圖像描述

Canvas 在邊界外繪制綠色圓圈,對於文本,您會看到藍色矩形也在文本邊界外繪制。

牢記這一點,您可以得出結論,它的大小僅對使用它進行一些計算有意義,而不是限制文本或任何繪圖。

您可以使用rememberTextMeasurer()來解決此問題,以測量循環中的文本,使用當前線寬與 canvas 寬度,哪些詞應該適合第一行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM