Android Question get line count of a label

ArminKH

Well-Known Member
hi i want to measure the line count of a label
here is my code
B4X:
Sub Activity_Create(FirstTime As Boolean)
    Dim lbl As Label
        lbl.Initialize("")
        Activity.AddView(lbl,10dip,10dip,100dip,70dip)
            lbl.Text = "test text , test text , test text , test text , test text , test text"
            lbl.TextSize = 12
            Log(getLineCount(lbl))
           
End Sub

private Sub getLineCount(TargetView As Object) As Int
    Dim Source = TargetView As JavaObject
    Return Source.RunMethod("getLineCount",Null)
End Sub

the above code always return 0 value
i know the ui must be refreshed and by using CallSubDelayed maybe my problem can be solved but my codes is in a while loop and i cant wait for callsubdelayed and if use callsubdelayed still my code not worked in a while loop
my problem is not just in activity create and this is just a sample to reproduce my problem
so please suggest a good solution
can we measure line count without javaobject?
thanx all
 

Mitchboo

Member
Licensed User
Longtime User
I tried this with StringUtils :

B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
    Dim lbl As Label
        lbl.Initialize("")
        Activity.AddView(lbl,10dip,10dip,100dip,370dip)
           lbl.Text = "The world is a dangerous place to live; not because of the people who are evil, but because of the people who don't do anything about it." _
           & Chr(13) & Chr(10) & "Albert Einstein"
           lbl.TextSize = 12
           Log(getLineCount(lbl))
  
End Sub

private Sub getLineCount(TargetView As Label) As Int
            Dim su As StringUtils
            Dim OneLineHeight As Long = su.MeasureMultilineTextHeight(TargetView, "T"&Chr(13)&Chr(10)&"T")/2 ' Get the height of two lines, so line spacing is here, divide by 2
            Dim H As Long = su.MeasureMultilineTextHeight(TargetView, TargetView.Text)
            Return(Ceil(H/OneLineHeight))
End Sub

It seems to work fine for common text sizes.

To obtain an accurate value for the height of one line, I measure the height of two, then divide by two, so I can factor in the line spacing.
 
Last edited:
Upvote 0

ArminKH

Well-Known Member
thank u
i know this and also we can at first measure the height of one line by using java object directly and then height of all line ....
and if i want to complete your code,we can use this one for measure the height of one line
B4X:
Dim Jo = TargetView As JavaObject
    HeightOfOneLine = Jo.RunMethod("getLineHeight",Null)
but i'm looking for the correct code of my code in first post
thank u
 
Upvote 0

Mitchboo

Member
Licensed User
Longtime User
but i'm looking for the correct code of my code in first post
thank u

No sweat. But you asked :

can we measure line count without javaobject?
So I tried to precisely suggest a method that does not use JavaObject.

Thank you for the snippet to get the line height. However, for some reason, it does not give the same height.
23 my way, 21 your way.
 
Upvote 0

ArminKH

Well-Known Member
No sweat. But you asked :


So I tried to precisely suggest a method that does not use JavaObject.

Thank you for the snippet to get the line height. However, for some reason, it does not give the same height.
23 my way, 21 your way.
Thank u
Yes excuse me i forgot my question :(
Thats the java method not my own code
And although the 2 difference is not matter when we rounding the result
And you should know SU.MultiLineTextHeight not return correct value when user increase and decrease the space between lines
So u should use this
TextHeight= SU.MultiLineTextHeight * LineSpace
 
Upvote 0

Mitchboo

Member
Licensed User
Longtime User
And although the 2 difference is not matter when we rounding the result
And you should know SU.MultiLineTextHeight not return correct value when user increase and decrease the space between lines

2 on 20 is not negligible : 10 %. It will create bad results. In my example, if I use the JavaObject method, it finds 15 lines instead of the right result 14.

You may have not noticed that I get the height of one line taking su.MultiLineTextHeight for two lines divided by two, so in fact I take into account any line spacing.

Good luck !
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
This code works on my device:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    lbl.Initialize("")
    Activity.AddView(lbl, 10dip, 10dip, 100dip, 70dip)
    lbl.Text = "test text , test text , test text , test text , test text , test text"
    lbl.TextSize = 12
    DoEvents
    Log(getLineCount(lbl))
End Sub

Private Sub getLineCount(TargetView As Object) As Int
    Dim Source = TargetView As JavaObject
    Return Source.RunMethod("getLineCount",Null)
End Sub
Without the DoEvents it returns 0.
 
Upvote 0

ArminKH

Well-Known Member
This code works on my device:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    lbl.Initialize("")
    Activity.AddView(lbl, 10dip, 10dip, 100dip, 70dip)
    lbl.Text = "test text , test text , test text , test text , test text , test text"
    lbl.TextSize = 12
    DoEvents
    Log(getLineCount(lbl))
End Sub

Private Sub getLineCount(TargetView As Object) As Int
    Dim Source = TargetView As JavaObject
    Return Source.RunMethod("getLineCount",Null)
End Sub
Without the DoEvents it returns 0.
Tnx
Yes but not works in a while loop even with do events
 
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
I think that your problem is in this line:
Return Round(HeightOfText/HeightOfOneLine)
If HeightOfText/HeightOfOneLine is bigger than 1.5 then Round returns 2.
Shouldn't you use:
Return Floor(HeightOfText/HeightOfOneLine)

You need to be more coherent with your questions !
In the code examples in the posts you refer to Return Source.RunMethod("getLineCount",Null).
But in the code example in the other thread you have your own getLineCount routine which doesn't call RunMethod("getLineCount",Null) !!??
So where exactly is the problem ?
 
Upvote 0

ArminKH

Well-Known Member
I think that your problem is in this line:
Return Round(HeightOfText/HeightOfOneLine)
If HeightOfText/HeightOfOneLine is bigger than 1.5 then Round returns 2.
Shouldn't you use:
Return Floor(HeightOfText/HeightOfOneLine)

You need to be more coherent with your questions !
In the code examples in the posts you refer to Return Source.RunMethod("getLineCount",Null).
But in the code example in the other thread you have your own getLineCount routine which doesn't call RunMethod("getLineCount",Null) !!??
So where exactly is the problem ?
Klaus i want measure line count in a while loop
I have 2 solution
1: Using java object which is not works in while loop
2: Using my own solution like my post above
My own solution return 2 and java object return 0
I think we should round the result because the line count cant be for example 1.63
But i have not any solution for this one
Some time this method return correct result and some time failed
It is depended to text , text size , device
I don't know what is the solution klaus i'm so confused
Thank.u
 
Last edited:
Upvote 0

ArminKH

Well-Known Member
If i use floor instead round then thats return correct value
But this always return correct value?
For example maybe the value is 0.96 then if i use floor then thats return 0
Also maybe the value be 1.99 then floor return 1!!
i want to use a way to works correctly at all
 
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
You need to put the DoEvents at the right places !
You need one after each TextSize change !

Attached a modified version.

Why do you use a Class and not just a Code Module ?
 

Attachments

  • sa1.zip
    33.3 KB · Views: 443
Upvote 0

ArminKH

Well-Known Member
You need to put the DoEvents at the right places !
You need one after each TextSize change !

Attached a modified version.

Why do you use a Class and not just a Code Module ?
Because this is a part of my library and now my lib was updated by your help
https://www.b4x.com/android/forum/threads/t8textsize-library-smart-string.56851/
thank u so much @klaus
but can u please explain a bit for me why this problem happen without DoEvents?
because the ui most be refreshed?
 
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
because the ui most be refreshed?
It seems that for some properties the OS needs some more time to refresh the view before executing the next instruction.
Otherwise the next instruction is executed before the refresh.
 
Upvote 0

ArminKH

Well-Known Member
It seems that for some properties the OS needs some more time to refresh the view before executing the next instruction.
Otherwise the next instruction is executed before the refresh.
Ok understood ;)
 
Upvote 0
Top