Although the solution provided by Brian Ngure is not working, because wrong offsets trigger crashes. I used his idea to create a working one (at least for me :D).
VisualTransformation { text ->
TransformedText(buildAnnotatedString {
if (maxSymbols < 3) {
append(text)
} else {
append(text.take(maxSymbols - 3))
append("...")
}
}, object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
return if (maxSymbols < 3) text.length else maxSymbols
}
override fun transformedToOriginal(offset: Int): Int {
return text.length
}
})
Where 3 == "...".length
In order for that to work you have to get maxSymbols that can be drawn on the screen.
You can do that in the onTextLayout
callback of the TextField
There are ready to use variables didOverflowWidth, didOverflowHeight, hasVisualOverflow
onTextLayout = { result ->
isTextOverflow = result.didOverflowWidth
},
If that's not working, you can get information about current text field width result.size.width
and by comparing that with the screen width from LocalContext.current.resources.displayMetrics.widthPixels
you can understand when there is an overflow. For some reason the dedicated variables are not working for me.
When the overflow happens, just use another variable to remember maxSymbols
and apply this transformation to the TextField and a decoration box, if you use one.
var isTextOverflow by remember { mutableStateOf(false) }
var maxSymbols: Int = remember(isTextOverflow) { if (isTextOverflow) text.text.length else 0 }
And also you might need to recreate the transformation as different symbols have different width and for different texts width might be different, but recreating transformation too often can be bad for performance.