Bug? MeasureMultilineTextHeight throws exception with label.width=-2

Status
Not open for further replies.

Widget

Well-Known Member
Licensed User
Longtime User
Although setting a label.width to -2 to auto size the width is rare (normally user is looking for auto height), the StringUtils.MeasureMultilineTextHeight should still be able to handle it without throwing an exception.

Example:
B4X:
Sub buAdjust_Click
    Private SU As StringUtils
    Label1.Width  = -2
    Log("Height="&SU.MeasureMultilineTextHeight(Label1, Label1.Text))
End Sub

MeasureMultilineTextHeight can't handle a label.width = -2, but it can handle a label.height=-2.


It throws an exception:
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Error occurred on line: 64 (Main)
java.lang.IllegalArgumentException: Layout: -2 < 0
at android.text.Layout.<init>(Layout.java:139)
at android.text.StaticLayout.<init>(StaticLayout.java:105)
at android.text.StaticLayout.<init>(StaticLayout.java:91)
at android.text.StaticLayout.<init>(StaticLayout.java:69)
at android.text.StaticLayout.<init>(StaticLayout.java:49)
at anywheresoftware.b4a.objects.StringUtils.MeasureMultilineTextHeight(StringUtils.java:50)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:710)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:339)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:249)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:167)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:163)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:78)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
** Activity (main) Pause, UserClosed = true **
 

Widget

Well-Known Member
Licensed User
Longtime User
This is not a bug. You shouldn't use -2 for the height or width.

Why not? Using -2 adjusts the height or width of the label to fit the text at the current textsize and is incredibly easy to use. Set it once when the Label is initialized and it adjusts the size automatically.

1) One alternative is to run something like:
Label1.Text = "Some new text which may occupy multiple lines"
Label1.Height = SU.MeasureMultilineTextHeight(Label1, Label1.Text))​

after every single assignment to Label1 (including calls to Subs). If I forget to do it, the Label1 height is incorrect. This would be a pain to maintain all this code.

2) Another alternative is to define a custom label view (MyLabelView) that will do it for me but that means the height won't get updated if I pass the MyLabelView.Label to a Sub() that manipulates the label text. I could create a duplicate set of Subs() so it accepts MyLabelView as a parameter, but that too is a pain to maintain all this code.

Is there another solution?

TIA
 

klaus

Expert
Licensed User
Longtime User
I don't understand your logic.
SU.MeasureMultilineTextHeight calculates the height of the text for a given view which has a given with.
How could the OS calculate a height for a given text without knowing the width.
You need at least one reference, the width in this case.
 

Widget

Well-Known Member
Licensed User
Longtime User
I don't understand your logic.
SU.MeasureMultilineTextHeight calculates the height of the text for a given view which has a given with.
How could the OS calculate a height for a given text without knowing the width.
You need at least one reference, the width in this case.

Which logic of mine are you referring to?
Are you referring to my original post#1 of using Label1.Width=-2?
If so, then you are correct. I didn't mean to imply to set both the Label1.Width=-2 and Label1.Height to -2 at the same time. Only one dimension needs to be set and the other dimension is calculated. The Log() statement was left in my code from when I had used "Label1.Height=-2". And that's when I noticed the exception showing up. The Log() statement serves no useful purpose when setting Label1.Width=-2.

When Erel said:
"This is not a bug. You shouldn't use -2 for the height or width."

did he mean "You shouldn't use -2 for the height and width (at the same time)."
And it is OK to use -2 for either the Width or the Height, but not both. If so, then it makes sense.
 

Widget

Well-Known Member
Licensed User
Longtime User
For me, setting
Label1.Width = -2
is wrong.
To measure the height you need to set the width with a fixed value.

It is unorthodox. Sure. I only reported it because it caused MeasureMultilineTextHeight() to throw an exception. Would I ever use it? Probably not.

But let's forget about that for now.

What I want to know is, is:

Label1.Width = 100dip
Label1.Height = -2

wrong?

Or is there a better (easier) way to auto-adjust the Label1 height for a given width?

TIA
 
Last edited:
Status
Not open for further replies.
Top