android:autoSizeTextType in Jetpack Compose

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.

Leave a Comment