Problem with ListView ItemHeight

Discorez

Member
Licensed User
Longtime User
Hi All!
I need dynamically update ListView ItemHeight which depends from SecondLabel height (lines count), but not all items receive the new size.
Screenshots and demo project is attached.
Where troubles?
:sign0085:
Code:
B4X:
Sub Process_Globals

End Sub

Sub Globals
   Dim EditText1 As EditText
   Dim LV As ListView
   Dim Button1 As Button
   Dim Label1 As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("main")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub Button1_Click
   Dim Count, i As Int
   LV.Clear
   SetItemHeight(EditText1.Text)
   For i = 0 To 50
      LV.AddTwoLines("Header " & i, SetLines(EditText1.Text))
   Next
End Sub


Sub SetLines(Count As Int) As String
   Dim i As Int
   Dim SB As StringBuilder

   SB.Initialize
   For i = 1 To Count
      If i <> Count Then SB.Append("Line " & i & CRLF) Else SB.Append("Line " & i)
   Next
   Return SB.ToString
End Sub

Sub SetItemHeight(Lines As Int)
   Dim C As Canvas
   
    C.Initialize(LV)
   LV.TwoLinesLayout.Label.Height = 2 * C.MeasureStringHeight("W", Typeface.DEFAULT, LV.TwoLinesLayout.Label.TextSize)
   LV.TwoLinesLayout.SecondLabel.Height = 2 * Lines * C.MeasureStringHeight("W", Typeface.DEFAULT, LV.TwoLinesLayout.SecondLabel.TextSize)
   LV.TwoLinesLayout.ItemHeight = (LV.TwoLinesLayout.Label.Height + LV.TwoLinesLayout.SecondLabel.Height)
   Label1.Text = "Items height: " & LV.TwoLinesLayout.ItemHeight
End Sub
 

Attachments

  • 1.png
    34.4 KB · Views: 441
  • 2.png
    34.4 KB · Views: 462
  • Test.zip
    6.9 KB · Views: 357
Last edited:

JonPM

Well-Known Member
Licensed User
Longtime User
Here you go:

B4X:
'Activity module
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.

End Sub

Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.

   Dim EditText1 As EditText
   Dim LV As ListView
   Dim Button1 As Button
   Dim Label1 As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("main")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub



Sub Button1_Click
   Dim Count, i As Int
   LV.Clear
   SetItemHeight(EditText1.Text)
   For i = 0 To 50
      LV.AddTwoLines("Header " & i, SetLines(EditText1.Text))
   Next
End Sub


Sub SetLines(Count As Int) As String
   Dim i As Int
   Dim SB As StringBuilder

   SB.Initialize
   For i = 1 To Count
      If i <> Count Then SB.Append("Line " & i & CRLF) Else SB.Append("Line " & i)
   Next
   Return SB.ToString
End Sub

Sub SetItemHeight(Lines As Int)
   Dim C As Canvas
   
    C.Initialize(LV)
   LV.TwoLinesLayout.Label.Height = 2 * C.MeasureStringHeight("W", Typeface.DEFAULT, LV.TwoLinesLayout.Label.TextSize)
   LV.TwoLinesLayout.SecondLabel.Height = 2 * Lines * C.MeasureStringHeight("W", Typeface.DEFAULT, LV.TwoLinesLayout.SecondLabel.TextSize)
   DoEvents
   LV.TwoLinesLayout.ItemHeight = LV.TwoLinesLayout.Label.Height + LV.TwoLinesLayout.SecondLabel.Height
   Label1.Text = "Items height: " & LV.TwoLinesLayout.ItemHeight
End Sub
 
Upvote 0

Discorez

Member
Licensed User
Longtime User
Klaus, I dont want to have different height item heights, I want to set items similar size.
Please, see second screenshot...
 
Upvote 0

Roger Garstang

Well-Known Member
Licensed User
Longtime User
You have to think of FirstLabel, SecondLabel, and ItemHeight as a template for all items. Each item can't have its own template that is a different size. It may appear to work at first, but it will blow up on you. I thought I was able to do it that way when I first used B4A too then the list goes nuts on scrolling.
 
Last edited:
Upvote 0

Roger Garstang

Well-Known Member
Licensed User
Longtime User
There are 3 layouts available. One of which is a single line and wouldn't work here, but you can modify the other two so you have 2 different sizes available. You could maybe make one that shows two lines and one that shows four or five lines.

Just don't use a bitmap for the twolines layout that has it and shift the two labels over then size how you need. When you insert two lines of less insert with the one you sized for two lines and when more than two lines insert with the one you sized for 4-5 lines.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
The working version (three changes; compare with your own code):
B4X:
Sub SetItemHeight(Lines As Int)
   Dim C As Canvas
   
   C.Initialize(LV)
   LV.TwoLinesLayout.Label.Height = C.MeasureStringHeight("yÎ", LV.TwoLinesLayout.Label.Typeface, LV.TwoLinesLayout.Label.TextSize)
   LV.TwoLinesLayout.SecondLabel.Height = Lines * C.MeasureStringHeight("yÎ", LV.TwoLinesLayout.SecondLabel.Typeface, LV.TwoLinesLayout.SecondLabel.TextSize)
   LV.TwoLinesLayout.ItemHeight = LV.TwoLinesLayout.SecondLabel.Top + LV.TwoLinesLayout.SecondLabel.Height

   Label1.Text = "Items height: " & LV.TwoLinesLayout.ItemHeight
   
   DoEvents
End Sub
 
Upvote 0

Discorez

Member
Licensed User
Longtime User
The working version
Hmm...
Works but isn't stable. I check it several times - items of different height (see screenshot)
I always thought what DoEvents is applied in loops, that the program would process messages queue...


B4X:
Sub SetItemHeight(Lines As Int)
    Dim C As Canvas
    
    C.Initialize(LV)
    LV.TwoLinesLayout.Label.Height = C.MeasureStringHeight("y�", LV.TwoLinesLayout.Label.Typeface, LV.TwoLinesLayout.Label.TextSize)
    LV.TwoLinesLayout.SecondLabel.Height = Lines * C.MeasureStringHeight("y�", LV.TwoLinesLayout.SecondLabel.Typeface, LV.TwoLinesLayout.SecondLabel.TextSize)
    LV.TwoLinesLayout.ItemHeight = LV.TwoLinesLayout.SecondLabel.Top + LV.TwoLinesLayout.SecondLabel.Height

    Label1.Text = "Items height: " & LV.TwoLinesLayout.ItemHeight
    
    DoEvents
End Sub
the item height turns out wrong (on the screenshot it is shown)
Informatix, what is the char - "y�"?
 

Attachments

  • 3.png
    34.9 KB · Views: 350
  • 4.png
    34.1 KB · Views: 363
Last edited:
Upvote 0

Informatix

Expert
Licensed User
Longtime User
the item height turns out wrong (on the screenshot it is shown)
Informatix, what is the char - "y�"?

Because you didn't use the given characters. They are "y" and "Î", a capital I with a circumflex (transformed by the forum in a question mark). They are respectively the lowest character and the highest character. I don't know another method to compute properly a label height. I usually add the underscore because with some fonts it is the lowest character.
 
Upvote 0

Penko

Active Member
Licensed User
Longtime User
I am having exactly the same problem. I have a List View which acts as a menu in my book. Yesterday, I was contacted by a user telling me he can't access the last two chapters(list view items). By doing a quick review, I found I don't have access to the last one on my HTC either. I took me two hours to fix, I involved a scroll view which contains the list view. If I start with a height of 1000dip and then resize to the proper height, and it seems to be working. Without that line, I lost items again.

In examples, I've seen some 30-40 items in a plain list view. I also thought the list view scrolls no matter how many items you have.

Sent from my Next7P12 using Tapatalk 2
 
Upvote 0

Discorez

Member
Licensed User
Longtime User
Erel, what about my question? (The demo project I provided above)
Try to set different quantity of lines several times (3->6->2->7) - ItemsHeight will be different for some items.

P.S. Also, if to click the button again, the height becomes identical for all items.
:BangHead:
 
Last edited:
Upvote 0

Penko

Active Member
Licensed User
Longtime User
Ρуский:
@Discorez, Извините за угон вашей темы форума.

English:
@Discorez, sorry for hijacking your forum topic.


@Erel, I am totally unable to reproduce this one. Is there any meaninful explanation when a ListView can't scroll to the last item but let's say cuts 2-3 items before the end?
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User

That won't solve your "Refresh" problem, but here's a perfect computation of the itemheight (tested with different number of lines and different devices):
B4X:
Sub SetItemHeight(Lines As Int)
   LV.TwoLinesLayout.SecondLabel.Color = Colors.blue

   Dim C As Canvas
   C.Initialize(LV)
   LV.TwoLinesLayout.SecondLabel.Height = Lines * C.MeasureStringHeight("y_Î", LV.TwoLinesLayout.SecondLabel.Typeface, LV.TwoLinesLayout.SecondLabel.TextSize)
   LV.TwoLinesLayout.SecondLabel.Height = LV.TwoLinesLayout.SecondLabel.Height - Lines + 4
   
   Dim Margin As Int
   Margin = 5dip
   LV.TwoLinesLayout.ItemHeight = LV.TwoLinesLayout.SecondLabel.Top + LV.TwoLinesLayout.SecondLabel.Height + Margin

   Label1.Text = "Items height: " & LV.TwoLinesLayout.ItemHeight
End Sub

The first line colors the label in blue to make the label height visible.
"Margin" is the margin between the label bottom and the item bottom.

By the way, what's your hardware and Android version?
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…