Android Question Autosize Label text in Android 14

ema01

Member
Licensed User
Longtime User
As erel rightly points out, this
is not a B4A bug, but a result of changes introduced by android 14.

So i have yet again to look into how to autozise labels fonts.
Googling a bit turns out that this should be the best (?) approach.

B4X:
'Optional, but required if you NEED the text to be single line.
Dim r As Reflector
r.Target = lbl
r.RunMethod2("setMaxLines", 1, "java.lang.int") '1 Because single line, use actual number of lines instead
    
Dim jo As JavaObject
jo.InitializeStatic("android.support.v4.widget.TextViewCompat")
jo.RunMethod("setAutoSizeTextTypeUniformWithConfiguration", Array(lbl, 1, 300, 1, 1))

the setMaxLines method is needed for text that you want to be single line, otherwise two things are going to happen
1) Label is multiline, Autosize will occupy as most area as possible making text multiline if necessary
2) Label is singleline, Autosize will set for max height. If the width is too low the text will be cropped
If you setMaxLines to 1 (or to whatever lines you want to show) and the label is multiline, Autosize will do what expected: show a single line, text size set to max, adjusted for both width and height.

AutoSize produces the expected result at all font scales, effectively working around the issue described above.
I take suggestions to further enhance the code (for example, get rid of reflections?)
 

ema01

Member
Licensed User
Longtime User
Exactly the line of code i was looking for (i didn't think i could cast as a java object, but of course i could)
 
Upvote 0

ema01

Member
Licensed User
Longtime User
A few days later, i'm faced with another issue:
I'm having troubles understangin when the text is autosized. From my tests it seems it's being autosized only when the object is in a layout and it's visible.
The old iterative method did not care about the object being visibile, at all, it just had to be initialized.
What i'm trying to do: I'm trying to make B4X Dialogs of the appropriate size.
I set a default width/height for a label, text is applied, text size is changed so it fits the label, the label (and underlying panel) size is adjusted and only then the dialog is shown.

This is how i resize the label
B4X:
Private Sub AdjustLblSize(lbl As Label)
    Dim w As Int
    Dim h As Int
    Dim su As StringUtils
    Dim cvs As B4XCanvas
    Dim lines() As String = Regex.Split(CRLF, lbl.Text)
    Dim fnt As B4XFont = xui.CreateFont(lbl.Typeface, lbl.TextSize)
    
    h = su.MeasureMultilineTextHeight(lbl, lbl.Text) + lbl.Padding(1) + lbl.Padding(3)
    
    cvs.Initialize(lbl)
    w = 0
    For idx = 0 To lines.Length - 1
        Dim wLine As Int = cvs.MeasureText(lines(idx), fnt).Width + lbl.Padding(0) + lbl.Padding(2) + 5dip
        If w < wLine Then w = wLine
    Next
    cvs.Release
    
    lbl.Width = w
    lbl.Height = h
End Sub

And works beautifully for every label in an active layout (though sometimes i still need a Sleep(0) between adjusting text size with code above and adjusting label size)
The problem i'm getting now is that it seems that the text size changes only after the B4XDialog.show method

** I tried already making the panel not visible, adding it to the B4XDialog Parent, which in this case is the activity itself, doesn't change the text size even if sleeping for 10 seconds.
** Another cause could be that there is no layout yet, This particular dialog i'm looking at happens before everything. It happens right after Activity Create, before i load any other layout and resource (the dialog contains a disclaimer before asking for permissions. Application data is loaded after permissions are granted/checked)
 
Upvote 0

ema01

Member
Licensed User
Longtime User
Nope, if the label is not visible, AutosizeTextView will not work.
So the ugly workaround is
- Make it transparent, textcolor transparent
- Add to the view
- Autosize Text
- Sleep(0)
- AdjustLblSize
- Remove from parent
- Assign text color etc
- Place in panel, resize panel
- B4XDialog.show
 
Upvote 0
Top