How to give different color to textDecoration?

816 Views Asked by At
    Text(
        text = "Told lee he'd be a millionaire",
        color = Color.White,
        textDecoration = TextDecoration.LineThrough
    )

The result of the above code is

enter image description here

I'd like to know if there's a way to change the color of the line that strikes through, The intended result would be something like

enter image description here

2

There are 2 best solutions below

0
Thracian On

Workaround for this would be using Modifier.drawWithContent{} and drawing line in front of text. This is only for single line text though. If you need to use for multiple lines need to calculate text height and apply each line

    Text(
    
        text = "Told lee he'd be a millionaire",
        color = Color.White,
        fontSize = 24.sp,
        textDecoration = TextDecoration.LineThrough
    )
    
    Text(
        modifier = Modifier
            .drawWithContent {
                drawContent()
                val strokeWidth = 2.dp.toPx()
                val verticalCenter = size.height / 2 + 2 * strokeWidth
                drawLine(
    
                    color = Color.Yellow,
                    strokeWidth = strokeWidth,
                    start = Offset(0f, verticalCenter),
                    end = Offset(size.width, verticalCenter)
                )
            },
        fontSize = 24.sp,
        text = "Told lee he'd be a millionaire",
        color = Color.White
    )

enter image description here

For multiline there can be many things to consider. But basically need to get line count, total height and width of each line.

var lineCount = 1
val lineList = mutableListOf<Float>()

Text(
    onTextLayout = { textLayoutResult ->
        lineCount = textLayoutResult.lineCount
        for(i in 0 until  lineCount) {
            lineList.add(textLayoutResult.getLineRight(i))
        }
    },
    modifier = Modifier
        .drawWithContent {
            drawContent()
            val strokeWidth = 2.dp.toPx()
            val center = size.height/(lineCount + 1)
            for (i in 1..lineCount) {
                val verticalCenter = i * center + 2 * strokeWidth

                drawLine(

                    color = Color.Yellow,
                    strokeWidth = strokeWidth,
                    start = Offset(0f, verticalCenter),
                    end = Offset(lineList[i-1].toFloat(), verticalCenter)
                )
            }
        },
    fontSize = 40.sp,
    text = "Told lee he'd be\n" +
            "new line",
    color = Color.White
)

enter image description here

0
user1852820 On
Box {

    var textLayoutResult by remember { mutableStateOf<TextLayoutResult?>(null) }

    Text(
        text = text,
        modifier = modifier.drawWithContent {
            drawContent()
            if (isLineThrough) {
                textLayoutResult?.apply {
                    val strokeWidth = 1.dp.toPx()
                    for (i in 0 until lineCount) {
                        val verticalCenter = (getLineTop(i) + ((getLineBottom(i) - getLineTop(i)) / 2)) + (2 * strokeWidth)
                        drawLine(
                            color = KDSColors.Red,
                            strokeWidth = strokeWidth,
                            start = Offset(-5f, verticalCenter),
                            end = Offset(getLineRight(i) + 5, verticalCenter)
                        )
                    }
                }
            }

        },
        onTextLayout = { textLayoutResult = it },
        style = TextStyle.BlackBold14,
    )
}