如何在 Jetpack Compose 中为文本添加点线/虚线下划线?

ale*_*ter 2 android android-jetpack-compose android-jetpack-compose-text

我正在尝试获取自定义 TextDecoration - DashUnderline。现有的答案仅适用于一行,我需要为每一行文本添加虚线。

在此输入图像描述

对于 TextView 我有一个类,但我不知道如何将其转换为 Compose。

class DashedUnderlineSpan(
    textView: TextView, color: Int, thickness: Float, dashPath: Float,
    offsetY: Float, spacingExtra: Float
) :
    LineBackgroundSpan, LineHeightSpan {
    private val paint: Paint
    private val textView: TextView
    private val offsetY: Float
    private val spacingExtra: Float
    override fun chooseHeight(
        text: CharSequence, start: Int, end: Int, spanstartv: Int, v: Int,
        fm: Paint.FontMetricsInt
    ) {
        fm.ascent -= spacingExtra.toInt()
        fm.top -= spacingExtra.toInt()
        fm.descent += spacingExtra.toInt()
        fm.bottom += spacingExtra.toInt()
    }

    override fun drawBackground(
        canvas: Canvas, p: Paint, left: Int, right: Int, top: Int, baseline: Int,
        bottom: Int, text: CharSequence, start: Int, end: Int, lnum: Int
    ) {
        val lineNum = textView.lineCount
        for (i in 0 until lineNum) {
            val layout = textView.layout
            val path = android.graphics.Path()
            path.moveTo(layout.getLineLeft(i), layout.getLineBottom(i) - spacingExtra + offsetY)
            path.lineTo(layout.getLineRight(i), layout.getLineBottom(i) - spacingExtra + offsetY)
            canvas.drawPath(path, paint)
        }
    }

    init {
        paint = Paint()
        paint.color = color
        paint.style = Paint.Style.STROKE
        paint.pathEffect = DashPathEffect(floatArrayOf(dashPath, dashPath), 0f)
        paint.strokeWidth = thickness
        this.textView = textView
        this.offsetY = offsetY
        this.spacingExtra = spacingExtra
    }
}
Run Code Online (Sandbox Code Playgroud)

ale*_*ter 15

我找到了一个解决方案:

\n
var layout by remember { mutableStateOf<TextLayoutResult?>(null) }\n\nText(\n    text = "\xd0\x98\xd1\x81\xd1\x82\xd0\xbe\xd1\x80\xd0\xb8\xd1\x8f \xd1\x83\xd0\xbd\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x80\xd1\x81\xd0\xb8\xd1\x82\xd0\xb5\xd1\x82\xd0\xb0",\n    style = MaterialTheme.typography.h3,\n    color = Color.Black,\n    onTextLayout = {\n        layout = it\n    },\n    modifier = Modifier.drawBehind {\n\n        layout?.let {\n            val thickness = 5f\n            val dashPath = 15f\n            val spacingExtra = 4f\n            val offsetY = 6f\n\n            for (i in 0 until it.lineCount) {\n                drawPath(\n                    path = Path().apply {\n                        moveTo(it.getLineLeft(i), it.getLineBottom(i) - spacingExtra + offsetY)\n                        lineTo(it.getLineRight(i), it.getLineBottom(i) - spacingExtra + offsetY)\n                    },\n                    Color.Gray,\n                    style = Stroke(width = thickness,\n                        pathEffect = PathEffect.dashPathEffect(floatArrayOf(dashPath, dashPath), 0f)\n                    )\n                )\n            }\n        }\n    }\n)\n
Run Code Online (Sandbox Code Playgroud)\n