Size of label to fit a string

RJB

Active Member
Licensed User
Longtime User
Hi,
Is there any way of calculating the size of label that will fit a given string? I have to add a varying amount to the Canvas.MeasureStringwidth and .....height to make the label large enough. That amount seems to vary with the string length and text size. Is there a way of finding out what that amount should be? I don't want to use e.g. label.width = -2 as I can't then find out the actual width.
Thanks
 

RJB

Active Member
Licensed User
Longtime User
Check AutoTextSizeLabel class: http://www.b4x.com/android/forum/posts/177986/

It sets the maximum text size that fits. Check the code. You should probably be able to change its implementation and instead of modifying the text size, modify the label width.

Thanks.
Setting padding to zero seems like something I could use but reading other posts looks like it doesn't actually set the text to top left as you would expect?
I think the only way to actually do it is using an imageview. seems crazy but.........
 
Upvote 0

RJB

Active Member
Licensed User
Longtime User
You do not need an ImageView. Have you tried AutoTextSizeLabel? You just need to modify the CheckSize sub and increase the width instead of the font size.
I'll take another look. I can vary the width, as long as I know what it has been set to and the offset of the text from the left. Ideally I don't want to vary the height. The height and the font size should be fixed, so I need to be able to put the text right at the top of the label so that the descenders fit in.
 
Upvote 0

RJB

Active Member
Licensed User
Longtime User
I'll take another look. I can vary the width, as long as I know what it has been set to and the offset of the text from the left. Ideally I don't want to vary the height. The height and the font size should be fixed, so I need to be able to put the text right at the top of the label so that the descenders fit in.
I've tried using Imageview but the width is still a problem. If you set it as follows:

B4X:
ImageView1.Initialize("")
ImageView1.Color = Colors.lightgray
Activity.AddView(ImageView1,0,0,1dip,1dip)
Dim textsize As Float = 24
Dim text As String = "The quick brown fox jumps over the lazy dogs back"       
Canvas.Initialize(Activity)
Dim Height As Int = Canvas.MeasureStringheight(text, Typeface.DEFAULT, textsize)' * 1dip
Dim width As Int = Canvas.MeasureStringwidth(text, Typeface.DEFAULT, textsize)' * 1dip
ImageView1.SetLayout(0,0,width,Height)
Canvas.Initialize(ImageView1)
Canvas.DrawText(text, 0, Height * 0.8, Typeface.DEFAULT, textsize, Colors.Red, "LEFT")
ImageView1.Bitmap = Canvas.Bitmap

then the text is cut short by varying amounts unless you use .MONOSPACE typeface. Am I doing something wrong?

Also is the TEXTSIZE parameter in pixels, DIP, or points?
Thanks
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
The code below will do it.
B4X:
Sub Globals
    Dim lblTest As Label
    Dim btnTextLong, btnTextShort As Button
  
    Dim bmpTest As Bitmap
    Dim cvsTest As Canvas
    Dim stu As StringUtils
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("main")
  
    bmpTest.InitializeMutable(1dip, 1dip)
    cvsTest.Initialize2(bmpTest)
  
    btnTextLong_Click
End Sub

Sub btnTextLong_Click
    lblTest.TextSize = 16
    SetTextAndWidth(lblTest, "Long long long long long long text")
End Sub

Sub btnTextShort_Click
    lblTest.TextSize = 24
    SetTextAndWidth(lblTest, "Short text")
End Sub

Sub SetTextAndWidth(lbl As Label, txt As String)
    lbl.Width = cvsTest.MeasureStringWidth(txt, lbl.Typeface, lbl.TextSize)
    lbl.Height = stu.MeasureMultilineTextHeight(lbl, txt)
    lbl.Text = txt
End Sub

Best regards.
 

Attachments

  • LabelAutoWidthHeight.zip
    7.2 KB · Views: 278
Upvote 0

RJB

Active Member
Licensed User
Longtime User
The code below will do it.
B4X:
Sub Globals
    Dim lblTest As Label
    Dim btnTextLong, btnTextShort As Button
 
    Dim bmpTest As Bitmap
    Dim cvsTest As Canvas
    Dim stu As StringUtils
End Sub
 
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("main")
 
    bmpTest.InitializeMutable(1dip, 1dip)
    cvsTest.Initialize2(bmpTest)
 
    btnTextLong_Click
End Sub
 
Sub btnTextLong_Click
    lblTest.TextSize = 16
    SetTextAndWidth(lblTest, "Long long long long long long text")
End Sub
 
Sub btnTextShort_Click
    lblTest.TextSize = 24
    SetTextAndWidth(lblTest, "Short text")
End Sub
 
Sub SetTextAndWidth(lbl As Label, txt As String)
    lbl.Width = cvsTest.MeasureStringWidth(txt, lbl.Typeface, lbl.TextSize)
    lbl.Height = stu.MeasureMultilineTextHeight(lbl, txt)
    lbl.Text = txt
End Sub

Best regards.

Thanks Erel and Klaus.

I've spent another few hours investigating and it looks like the problem lays within the device, android version or default font.
I tried the following on two devices, one a 10inch tablet running android 4.0.4 the other a 7inch tablet running 2.2:
B4X:
Dim Canvas1 As Canvas
 
    Dim lbl1 As Label
    Dim character As Float = 0
    Dim runningtotal As Float = 0
    Dim width As Float = 0
    Dim text1 As String = "TTTtttt T t f fffffffo o oooo The quick brown fox jumps over the lazy dogs back"
    Dim text2 As String = ""
    Dim textsize As Int = 16
    Dim difference As Float = 0
   
    Canvas1.Initialize(Activity)
    lbl1.Initialize("")
    Activity.AddView(lbl1,0dip,0dip,1dip,24dip)
    lbl1.Color = Colors.blue
    lbl1.text = ""
    lbl1.Typeface = Typeface.DEFAULT
    lbl1.textsize = textsize
 
    For i = 0 To text1.Length - 1
        text2 = text2 & text1.SubString2(i, i + 1)
        character = Canvas1.MeasureStringWidth(text1.SubString2(i, i + 1), Typeface.DEFAULT_BOLD, textsize)
        runningtotal = runningtotal + character
        width = Canvas1.MeasureStringWidth(text2, Typeface.DEFAULT_BOLD, textsize)
        difference = runningtotal - width
        Log(text1.SubString2(i, i + 1) & " : " & character & " : " & runningtotal & " : " & width & " : " & difference)
        lbl1.text = text2
        lbl1.width = width
    Next

On the 10inch I get the following log:
T : 11 : 11 : 11 : 0
T : 11 : 22 : 21 : 1
T : 11 : 33 : 31 : 2
t : 7 : 40 : 37 : 3
t : 7 : 47 : 43 : 4
t : 7 : 54 : 49 : 5
t : 7 : 61 : 55 : 6
: 4 : 65 : 59 : 6
T : 11 : 76 : 69 : 7
: 4 : 80 : 72 : 8
t : 7 : 87 : 78 : 9
: 4 : 91 : 82 : 9
f : 7 : 98 : 88 : 10
: 4 : 102 : 91 : 11
f : 7 : 109 : 97 : 12
f : 7 : 116 : 103 : 13
f : 7 : 123 : 109 : 14
f : 7 : 130 : 115 : 15
f : 7 : 137 : 121 : 16
f : 7 : 144 : 127 : 17
f : 7 : 151 : 133 : 18
o : 10 : 161 : 142 : 19
: 4 : 165 : 146 : 19
o : 10 : 175 : 156 : 19
: 4 : 179 : 160 : 19
o : 10 : 189 : 170 : 19
o : 10 : 199 : 179 : 20
o : 10 : 209 : 188 : 21
o : 10 : 219 : 197 : 22
: 4 : 223 : 201 : 22
T : 11 : 234 : 211 : 23
h : 9 : 243 : 219 : 24
e : 9 : 252 : 227 : 25
: 4 : 256 : 230 : 26
q : 9 : 265 : 239 : 26
u : 9 : 274 : 248 : 26
i : 4 : 278 : 252 : 26
c : 9 : 287 : 260 : 27
k : 8 : 295 : 267 : 28
: 4 : 299 : 271 : 28
b : 9 : 308 : 280 : 28
r : 5 : 313 : 284 : 29
o : 10 : 323 : 294 : 29
w : 12 : 335 : 306 : 29
n : 9 : 344 : 315 : 29
: 4 : 348 : 319 : 29
f : 7 : 355 : 325 : 30
o : 10 : 365 : 334 : 31
x : 8 : 373 : 342 : 31
: 4 : 377 : 346 : 31
j : 4 : 381 : 350 : 31
u : 9 : 390 : 359 : 31
m : 14 : 404 : 373 : 31
p : 9 : 413 : 382 : 31
s : 9 : 422 : 390 : 32
: 4 : 426 : 394 : 32
o : 10 : 436 : 404 : 32
v : 8 : 444 : 412 : 32
e : 9 : 453 : 421 : 32
r : 5 : 458 : 425 : 33
: 4 : 462 : 429 : 33
t : 7 : 469 : 435 : 34
h : 9 : 478 : 443 : 35
e : 9 : 487 : 451 : 36
: 4 : 491 : 454 : 37
l : 4 : 495 : 458 : 37
a : 9 : 504 : 466 : 38
z : 9 : 513 : 474 : 39
y : 8 : 521 : 482 : 39
: 4 : 525 : 486 : 39
d : 9 : 534 : 495 : 39
o : 10 : 544 : 504 : 40
g : 9 : 553 : 512 : 41
s : 9 : 562 : 521 : 41
: 4 : 566 : 525 : 41
b : 9 : 575 : 534 : 41
a : 9 : 584 : 542 : 42
c : 9 : 593 : 550 : 43
k : 8 : 601 : 557 : 44
The difference figure increases and there is a blank space at the end of the displayed text.
When run on the 7inch device the difference is always zero and there is no space at the end.
Any thoughts?
Thanks
 
Upvote 0

RJB

Active Member
Licensed User
Longtime User
Thanks Erel and Klaus.

............
The difference figure increases and there is a blank space at the end of the displayed text.
When run on the 7inch device the difference is always zero and there is no space at the end.
Any thoughts?
Thanks

Well I guess I'll have to stick with mono spaced fonts for now!!!!!!!!!!
 
Upvote 0
Top