Autosize text to fit max width of a Glance Widget?

118 views Asked by At

I am currently learning to handle Glance Widgets and I cannot find a "fit to width" for a Text() field. Making the text unreadable based on text-scaling setup on users phones

For large scale fonts it looked like this:
Fontscale 1.3
I wanted results like this, on all scales:
Fontscale 1.3 with autotextestimate


I gave it a shot and created this workaround, but my Android/Kotlin experience is limited.
Are there functions that are better todo the same?
val Float.toPx get() = this * Resources.getSystem().displayMetrics.density

fun autoSizeFont(text: String, availableWidthInPx: Int, fontSize: Float = 30.0F): TextUnit {
    val bounds = Rect()
    val paint = TextPaint()
    var fontSizeReturn = fontSize

    val scale = Resources.getSystem().configuration.fontScale

    while(true)
    {
        paint.textSize = (fontSizeReturn * Resources.getSystem().displayMetrics.density) //Try fontsize as sp
        paint.getTextBounds(text, 0, text.length, bounds) //In pixels
        if(availableWidthInPx >= bounds.width())
        {
            fontSizeReturn /= scale //Remove scalefactor before returning fontSize
            return fontSizeReturn.sp 
        }
        else
        {
            fontSizeReturn *= 0.95F //Did not fit, try 5% off
        }
        if(fontSizeReturn <= 0.0F) break
    }

    return TextUnit.Unspecified
}

Using autoSizeFont() in a composition it will look like something like this:

@Composable
fun Widget(text: String) {
    val defaultWeight = GlanceModifier.fillMaxWidth()
    val size = LocalSize.current

        Text(
            text = weatherInfo.header,
            style = TextStyle(
                fontSize = autoSizeFont(text, size.width.value.toPx.toInt()),
                textAlign = TextAlign.Center
                ),
            modifier = defaultWeight,
            maxLines = 1
        )
}

If you are experienced with Glance widgets and how to make the layout work on every scale and size; I would like to hear your tips. Maybe a way to override / force the fontScale = 1.0 always (Like i do in Flutter) or other methods.

0

There are 0 answers