Is there a way to style separate parts of the text...
# compose
n
Is there a way to style separate parts of the text in a TextField? If I try to do a visual transformation and create a new annotated string with separate color of different parts of the string it doesn’t do anything 🤔 ?
👀 2
👌 1
Trying to achieve the following effect.
d
What is your code currently rendering then?
n
Just black text
d
The snippet of choice you've shared looks fine to me. Maybe you haven't applied the transformation to the right text field 🤷🏼
n
I know the transformation is applied since the masking works, it's just the split in coloring that doesn't
d
What happens if you swap black and grey?
Also log the two variables and see if they're correct
🙏 1
n
@Dominaezzz yeah you were right i added to out instead of padOut -_- This here works
Copy code
class MaskVisualTransformation(private val mask: String, private val hint: String) : VisualTransformation {

    private val specialSymbolsIndices = mask.indices.filter { mask[it] != '#' }

    override fun filter(text: AnnotatedString): TransformedText {
        return TransformedText(buildAnnotatedString(
            text.text, hint
        ), offsetTranslator())
    }

    private fun buildAnnotatedString(text: String, hint: String): AnnotatedString {
        var out = ""
        var maskIndex = 0

        text.forEach { char ->
            while (specialSymbolsIndices.contains(maskIndex)) {
                out += mask[maskIndex]
                maskIndex++
            }
            out += char
            maskIndex++
        }


        val padString = hint.takeLast(hint.length - text.length)
        var padOut = ""
        padString.forEach { char ->
            while (specialSymbolsIndices.contains(maskIndex)) {
                padOut += mask[maskIndex]
                maskIndex++
            }
            padOut += char
            maskIndex++
        }

        val annotatedText = buildAnnotatedString {
            //append your initial text
            withStyle(
                style = SpanStyle(
                    color = Color.Black,
                )
            ) {
                append(out)
            }
            withStyle(
                style = SpanStyle(
                    color = Color.Blue,
                )
            ) {
                append(padOut)
            }
        }

        return annotatedText
    }

    private fun offsetTranslator() = object : OffsetMapping {
        override fun originalToTransformed(offset: Int): Int {
            val offsetValue = offset.absoluteValue
            if (offsetValue == 0) return 0
            var numberOfHashtags = 0
            val masked = mask.takeWhile {
                if (it == '#') numberOfHashtags++
                numberOfHashtags < offsetValue
            }
            return masked.length + 1
        }

        override fun transformedToOriginal(offset: Int): Int {
            return mask.take(offset.absoluteValue).count { it == '#' }
        }
    }
}