I use the following to adjust the font size with respect to the available width:
val textStyleBody1 = MaterialTheme.typography.body1
var textStyle by remember { mutableStateOf(textStyleBody1) }
var readyToDraw by remember { mutableStateOf(false) }
Text(
text = "long text goes here",
style = textStyle,
maxLines = 1,
softWrap = false,
modifier = modifier.drawWithContent {
if (readyToDraw) drawContent()
},
onTextLayout = { textLayoutResult ->
if (textLayoutResult.didOverflowWidth) {
textStyle = textStyle.copy(fontSize = textStyle.fontSize * 0.9)
} else {
readyToDraw = true
}
}
)
To adjust the font size based on height, play around with the Text
composable’s attributes and use didOverflowHeight
instead of didOverflowWidth
:
val textStyleBody1 = MaterialTheme.typography.body1
var textStyle by remember { mutableStateOf(textStyleBody1) }
var readyToDraw by remember { mutableStateOf(false) }
Text(
text = "long text goes here",
style = textStyle,
overflow = TextOverflow.Clip,
modifier = modifier.drawWithContent {
if (readyToDraw) drawContent()
},
onTextLayout = { textLayoutResult ->
if (textLayoutResult.didOverflowHeight) {
textStyle = textStyle.copy(fontSize = textStyle.fontSize * 0.9)
} else {
readyToDraw = true
}
}
)
In case you need to synchronize the font size across multiple items in a list, save the text style outside of the composable function:
private val textStyle = mutableStateOf(MaterialTheme.typography.body1)
@Composable
fun YourComposable() {
Text(...)
}
This is certainly not perfect, as it might take some frames until the size fits and the text draws finally.