https://kotlinlang.org logo
#compose
Title
# compose
n

nlindberg

07/02/2022, 1:35 PM
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

Dominaezzz

07/02/2022, 3:34 PM
What is your code currently rendering then?
n

nlindberg

07/02/2022, 3:47 PM
Just black text
d

Dominaezzz

07/02/2022, 3:50 PM
The snippet of choice you've shared looks fine to me. Maybe you haven't applied the transformation to the right text field 🤷🏼
n

nlindberg

07/02/2022, 3:55 PM
I know the transformation is applied since the masking works, it's just the split in coloring that doesn't
d

Dominaezzz

07/02/2022, 4:02 PM
What happens if you swap black and grey?
Also log the two variables and see if they're correct
🙏 1
n

nlindberg

07/04/2022, 8:30 AM
@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 == '#' }
        }
    }
}
6 Views