I'm making a simple TextField `VisualTransformatio...
# compose
j
I'm making a simple TextField
VisualTransformation
to ignore blank spaces, but when I tap the space bar multiple times and then I try to undo the typing it's counting all the blank spaces that were ignored, as seen in the video. Also, when I type two blank spaces it transforms them into a "." character. Any idea what I might be doing wrong?
Copy code
val ignoreBlanksVisualTransformation = VisualTransformation { text ->
    val blanksCount = text.text.count { it.toString().isBlank() }
    val transformedText = text.text.filterNot { it.toString().isBlank() }

    TransformedText(AnnotatedString(transformedText), object : OffsetMapping {
        override fun originalToTransformed(offset: Int) = offset - blanksCount
        override fun transformedToOriginal(offset: Int) = offset + blanksCount
    })
}
e
.
-insertion is the behavior of many keyboards. "Gboard settings » Text correction » Double-space period" for example
today i learned 1
what is your goal here? if it's to keep but hide all spaces, then the most straightforward thing to do would be to replace them with WJ or ZWS, e.g.
Copy code
val visualTransformation = VisualTransform { text ->
    TransformedText(
         AnnotatedString(text.text.replace("""\s""".toRegex(), "\u200B")),
        OffsetMapping.Identity
    )
}
if it's to prevent the user for inserting spaces, you can do that directly,
Copy code
private fun TextFieldValue.filtered(predicate: (Char) -> Boolean): TextFieldValue = copy(
    text = text.filter(predicate),
    selection = selection.adjustForFilter(text, predicate),
    composition = composition?.adjustForFilter(text, predicate),
)

private fun TextRange.adjustForFilter(text: String, predicate: (Char) -> Boolean): TextRange =
    TextRange(
        start = text.subSequence(0, start).count(predicate),
        end = text.subSequence(0, end).count(predicate),
    )

var textValue by remember { mutableStateOf(TextFieldValue()) }
TextField(
    value = textValue,
    onValueChange = { text -> textValue = text.filtered { !it.isWhitespace()} },
)
🙏 1
j
That's so much simpler, I haven't used the
TextFieldValue
override so it didn't cross my mind. Yeah I just want the user to not be able to type spaces