https://kotlinlang.org logo
#compose
Title
# compose
d

dagomni

05/19/2020, 6:06 PM
Hi! Is there an alternative in Compose Text for TextView's autoSize text scaling?
l

Leland Richardson [G]

05/19/2020, 9:18 PM
cc @Siyamed
💙 1
s

Siyamed

05/19/2020, 9:18 PM
No there is not
👍 1
We don't have plans to implement it in near future either
If you can describe the importance we might reprioritize
We had a good amount of assumptions in terms of priority. Some of which is possibly wrong.
d

dagomni

05/20/2020, 11:11 AM
@Siyamed I took a chance with Compose and I'm currently rewriting our app (175k+ downloads) from scratch. I realize of course that the API may significantly change and that there are things missing currently, so when no official support will be provided for a feature, I'll be forced to implement it on my own somehow anyway. We have a few places where we have to scale the text that are crucial to our UI (custom toolbars etc.) and it can't be done differently with current design (which will stick around for a few more years), so in my case it's really important.
l

Leland Richardson [G]

05/20/2020, 1:45 PM
Can you elaborate on the actual use case? What do you mean by custom toolbars etc...
d

dagomni

05/20/2020, 3:24 PM
Username text could be split in worst case scenario but the amounts need to fit in a single line inside the bubbles
l

Leland Richardson [G]

05/20/2020, 4:58 PM
seems like you could accomplish this with a custom modifier
the modifier would do a combination of recording the measured size from the text + applying a scale transform
d

dagomni

05/20/2020, 5:09 PM
Yeah that's what I'll probably end up doing now that I know there's no plan to support it in the near future, I was just hoping there is an official implementation 🤷‍♂️
s

Siyamed

05/20/2020, 5:11 PM
it is one of the existing android features, therefore we want to have it . based on our initial plan, I would not expect it to be implemented in the next ~6 months.
we want to make sure that we have right now works, and we have other “important” features such as link, fonts, selection etc done.
👌 2
m

Mantas Varnagiris

06/30/2020, 6:20 AM
@dagomni did you manage to write autosize modifier?
d

dagomni

06/30/2020, 8:09 AM
@Mantas Varnagiris unfortunately not yet, I have reprioritized the work a bit 🤷‍♂️
m

Mantas Varnagiris

06/30/2020, 5:16 PM
Ok I will try to take a look at this. I will share my code if I succeed 😉
I'm not entirely sure how to find measured text size. Could someone point me in the right direction?
s

Siyamed

06/30/2020, 5:52 PM
Text has onLayoutResult callback
It provides TextLayoutResult ehich has a bunch of values and functions
m

Mantas Varnagiris

06/30/2020, 5:53 PM
Ah yes I see. Thanks that is super helpful!
So I managed to make it. Pretty basic version but that is all I needed. First created modifier that removes size constraints from text view
Copy code
class UnconstrainedSizeModifier : LayoutModifier {
    override fun MeasureScope.measure(measurable: Measurable, constraints: Constraints, layoutDirection: LayoutDirection): MeasureResult {
        val placeable = measurable.measure(constraints.copy(maxWidth = Constraints.Infinity, maxHeight = Constraints.Infinity), layoutDirection)
        return layout(placeable.width, placeable.height) {
            placeable.place(0, 0)
        }
    }
}

fun Modifier.unconstrainedSize() = this + UnconstrainedSizeModifier()
And then
Copy code
WithConstraints(modifier = Modifier.fillMaxSize()) {
        var sizeRequiredToDraw by state { IntSize(0, 0) }
        val canvasWidth = maxWidth.toPx()
        val canvasHeight = maxHeight.toPx()
        val scale = remember(sizeRequiredToDraw, maxWidth, maxHeight) {
            val widthRatio = canvasWidth / sizeRequiredToDraw.width
            val heightRatio = canvasHeight / sizeRequiredToDraw.height
            min(widthRatio, heightRatio)
        }

        Text(
            modifier = Modifier.wrapContentSize().unconstrainedSize().drawLayer(scaleX = scale, scaleY = scale),
            fontSize = 50.sp, // max size
            text = "This is your text",
            onTextLayout = {
                sizeRequiredToDraw = it.size
            }
        )
    }
Not sure if this is the most efficient way though but it works for now
In short - allow text to layout without any constraints, then detect what is the scale difference between text and view bounds and scale that text
s

Siyamed

06/30/2020, 8:19 PM
No line break?
Makes sense for the possibly short labels
m

Mantas Varnagiris

06/30/2020, 8:20 PM
for my case I don't need it - unless text itself has line breaks
👍 1
I would have made a library for this - but this solution is not universal, so just posted how I achieved it for my case - might be useful for someone else
s

Siyamed

06/30/2020, 8:21 PM
You can also (not required) create a Paragraphintrinsics object for lon line break length and ask for paragraphIntrinsic.maxIntrsnsics(width/height)
m

Mantas Varnagiris

06/30/2020, 8:23 PM
I see. Might be interesting to make a more multi-purpose
AutoSizeText
3 Views