iOS Question CustomListView resizing problems

jhagerup

Member
Licensed User
Longtime User
I'm trying to present some header - detail data using clv, but have a (couple of) sizing problems.
When stepping through code (clv.add) every things looks nearly OK, i.e. the and width of the header and detail labels are the same, the height of the header is too small, the height of the details are too small, but seems to respect the multiline setting.
But in the end everything is a mess. The headers are OK (apart from the height), but the width of the details are changed, the heights of the panels are nearly OK, but the multiline label is no longer multiline.

Replacing the "original" multiline labels in code can solve the multiline problem, but is this nessesary and what about the widths and heights.

Any suggestions ?

Samplecode attached.
 

Attachments

  • clvResize.zip
    51.3 KB · Views: 228

Erel

B4X founder
Staff member
Licensed User
Longtime User
This code will help you get started:
B4X:
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'Public variables can be accessed from all modules.
   Public App As Application
   Public NavControl As NavigationController
   Private Page1 As Page
   Private clvType1 As CustomListView
   Private lHeaderTid As Label
   Private lHeaderAktivitet As Label
   Private lHeaderSted As Label

   Private lDetailTid As Label
   Private lDetailAktivitet As Label
   Private lDetailSted As Label
   Private ItemHeight As Double = 40
   
End Sub

Private Sub Application_Start (Nav As NavigationController)
   NavControl = Nav
   Page1.Initialize("Page1")
   Page1.Title = "Page 1"
   Page1.RootPanel.Color = Colors.White
   Page1.RootPanel.LoadLayout("infopagetype1")
   clvType1.Initialize(Me, "clvType1", 100%X)
   Page1.RootPanel.AddView(clvType1.AsView, 0, ItemHeight, 100%x, 100%y - ItemHeight)
   NavControl.ShowPage(Page1)
   
   Dim p As Panel
   p.Initialize("")
   p.Color = Colors.White
   p.SetLayoutAnimated(0, 0, 0, 0, 100%x, ItemHeight)
   p.LoadLayout("infoDetailType1")
   Dim s As StringBuilder
   s.Initialize
   s.Append("OK")
   lDetailTid.Text= s
   lDetailAktivitet.Text = s
   lDetailSted.Text ="test"
   clvType1.Add(p, ItemHeight,"")
   For i=1 To 3
     Dim p As Panel
     p.Initialize("")
     p.Color = Colors.White
     p.SetLayoutAnimated(0, 0, 0, 0, 100%x, ItemHeight)
     p.LoadLayout("infoDetailType1")
     Dim s As StringBuilder
     s.Initialize
     For j=i To 4
       s.Append("text - ")
     Next
     lDetailTid.Text= s
     lDetailAktivitet.Text = s
     lDetailSted.Text ="text"
     clvType1.Add(p, ItemHeight,"")
   Next
End Sub

Private Sub Page1_Resize(Width As Int, height As Int)
   clvType1.SetSize(Width, height - ItemHeight)
End Sub
 
Upvote 0

jhagerup

Member
Licensed User
Longtime User
Thanks Erel. I appriciate your help (and B4x) very much.
But I'm still far from my goal. Your code produces this (erel.png), but I'm trying to achieve something like this (jan.png).
To do that I replaced the clvType1.add(p, ItemHeight, "") with clvType1.add(replacePanel(s), panelHeight, "").

B4X:
Sub replacePanel(s As String) As Panel
    Dim tempPanel As Panel
    tempPanel.Initialize("")
    tempPanel.LoadLayout("infoDetailType1")
    Dim h As Double
    Dim p As Panel
    p.Initialize("")
    Dim lDT As Label
    lDT.Initialize("")
    lDT.SetBorder(1,Colors.Black,0)
    lDT.Top=lDetailTid.Top
    lDT.Width=lDetailTid.Width
    lDT.Multiline=True
    lDT.Font = lDetailTid.Font
    lDT.text=s
    lDT.SizeToFit

    Dim lDA As Label
    lDA.Initialize("")
    lDA.SetBorder(1,Colors.Black,0)
    lDA.Top=lDetailAktivitet.Top
    lDA.Width=lDetailAktivitet.Width
'    lDA.Multiline=True
    lDA.Font = lDetailAktivitet.Font
    lDA.text=s
    lDA.SizeToFit

    Dim lDS As Label
    lDS.Initialize("")
    lDS.SetBorder(1,Colors.Black,0)
    lDS.Top=lDetailSted.Top
    lDS.Width=lDetailSted.Width
    lDS.Multiline=True
    lDS.Font = lDetailSted.Font
    lDS.text="text"
    lDS.SizeToFit

    p.AddView(lDT,lDetailTid.Left,lDetailTid.Top,lDetailTid.Width,lDT.height)
    h=lDT.height
    p.AddView(lDA,lDetailAktivitet.Left,lDetailAktivitet.Top,lDetailAktivitet.Width,lDA.height)
    h=Max(h,lDA.height)
    p.AddView(lDS,lDetailSted.Left,lDetailSted.Top,lDetailSted.Width,lDS.height)
    h=Max(h,lDS.height)
    panelHeight = h
    Return p
   
End Sub

Is this the only way to do it ?
And, as you can see I can't find the right height (panelHeight) and have a little problem with the widths (sizeToFit changes the fontSize)
 

Attachments

  • erel.png
    erel.png
    30.2 KB · Views: 264
  • jan.png
    jan.png
    36.3 KB · Views: 246
Upvote 0

jhagerup

Member
Licensed User
Longtime User
Do you really mean that I have to do a "manual" wrapping ?
In that case I miss the StringUtils.MeasureMultiLineTextHeight from B4A ;-)
And I assume that the replacePanel is the "right" way.
 
Upvote 0

jhagerup

Member
Licensed User
Longtime User
It doesn't seem to make any difference, so I think I'll settle with adding 2/3 fontSize. Dirty, but it looks OK.

Once again, Thanks for your help
 
Upvote 0

jhagerup

Member
Licensed User
Longtime User
Erel.
I believe that I now have solved all my problems with resizing - my own, of cause.
SizeToFit works as expected.
But my (hopefully) last problem took som time to figure out. I needed horizontal scroll, but clv.SetSize didn't work as expected. So, after "playing" with ScrollView I think that I found a bug in SetSize:
sv.SetLayoutAnimated(0, 0, sv.Left, sv.Top, width, height) should be:
sv.SetLayoutAnimated(0, 0, sv.Left, sv.Top, sv.width, height)
If ScrollView width is the same as ContentWith there is nothing to scroll.

And thanks for the new Designer in B4j. A major improvement that will save a lot of time ;-)
 
Upvote 0

jhagerup

Member
Licensed User
Longtime User
Well, you will have to modify the code in CustomListView to change the ScrollView width. "Normal" developpers shouldn't have to do that. They would expect that horizontal scrolling is possible.
Consider the following:

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public App As Application
    Public NavControl As NavigationController
    Private Page1 As Page
    Private clv As CustomListView   
    Private contentWidth As Int = 0
    Private ItemHeight As Double = 40
     
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.RootPanel.Color = Colors.White
    clv.Initialize(Me, "clv", 100%X)
    Page1.RootPanel.AddView(clv.AsView, 0, 0, 100%x, 100%y)
    NavControl.ShowPage(Page1)
    Dim p As Panel
    p.Initialize("")
    For i = 1 To 3
        Dim l As Label
        l.Initialize("")
        l.Text = "Label # " & i
        l.Width = 100%x/2
        p.AddView(l, contentWidth, 0, l.Width, ItemHeight)
        contentWidth = contentWidth + l.Width
    Next
    clv.Add(p, ItemHeight, "")
End Sub

Private Sub Page1_Resize(Width As Int, height As Int)
    clv.SetSize(contentWidth, 100%y)
End Sub

Wouldn't you expect to able to scroll to see all 3 labels ?
 
Upvote 0
Top