Android Question Scrollview - problems with panel and view size

TyneBridges

Member
Licensed User
Longtime User
Can anyone see what I'm doing wrong in the following code, based on an example by Klaus? I'm trying to ensure that the Label view EntryBox is always large enough for the text it contains, which can vary from a few hundred characters to more than 3000. The code below seems to work fine for short texts but not for ones over about 1500 characters. I can't get EntryBox to expand sufficiently, even specifying a stupidly large size by manually adding units. (My commented out code starting "If EntryHeight > 1500") Am I confusing the size measures? I'm often not sure in B4A what the default unit of measurement is, or what suffix I should add to a number when specifying a size for a view.

Any help would be gratefully accepted.

B4X:
Sub ShowTableInFullView(OurQry As String)
Dim i As Int, EntryHeight As Int, PanelHeight As Int, PanelTop As Int, Hits As Int, HitStr As String, Place As String
    G.SQL1.Initialize(G.DBFileDir, G.DBFileName, True)
    Try
        G.SQL1.BeginTransaction
        G.ListTable = DBUtils.ExecuteMemoryTable(G.SQL1, OurQry, Null, 0)   
        PanelTop = 0
        PanelHeight = 110%y ' Must be greater than the screen size to scroll?
        Hits = G.ListTable.Size
        If Hits = 1 Then
            HitStr = Hits & " record found"
        Else
            HitStr = Hits & " records found"
        End If
        HitBox.Text = HitStr
        If Hits = 0 Then
            Msgbox("No results for query " & OurQry, G.AppName)
        Else
        For i = 0 To Hits - 1
            Dim Row () As String
            Row = G.ListTable.Get(i) ' This fills the row
            ' We have a set of labels for each record shown
            Dim DtBox As Label
            Dim WthrBox As Label
            Dim EntryBox As Label
           
            ' Add inner panel - once for each hit!
            Dim InnerPnl As Panel
            InnerPnl.Initialize("")
            pnlScroll.AddView(InnerPnl, 0, PanelTop, 100%x, 100%y)
           
            ' Views on our panel
            HitBox.Initialize("HitBox")
             DtBox.Initialize("dtBox")   
            WthrBox.Initialize("WthrBox")
            EntryBox.Initialize("EntryBox")
            DtBox.Initialize("")
            HitBox.TextColor = Colors.Black
           
            ' Params below are View name, Left, Top, Width, Height
            InnerPnl.AddView(DtBox, 0, 60dip, 25%x - 2dip, 60dip - 2dip)
            Dim JO As JavaObject = DtBox
             JO.Runmethod("setPadding", Array As Object(10dip, 10dip, 10dip, 10dip))
            DtBox.Color = Colors.White
            DtBox.TextColor = Colors.Black
            DtBox.Tag = "Date"
           
            WthrBox.Initialize("")
            InnerPnl.AddView(WthrBox, 25%x + 2dip, 60dip, 75%x - 2dip, 60dip - 2dip)
            Dim JO As JavaObject = WthrBox
             JO.Runmethod("setPadding", Array As Object(10dip, 10dip, 10dip, 10dip))
            WthrBox.Color = Colors.White
            WthrBox.TextColor = Colors.Black
            WthrBox.Tag = "Wthr"
           
            EntryBox.Initialize("")
            InnerPnl.AddView(EntryBox, 0, 122dip, 100%x, 100%y-WthrBox.Height)
            Dim JO As JavaObject = EntryBox
             JO.Runmethod("setPadding", Array As Object(10dip, 10dip, 10dip, 10dip))
            EntryBox.Color = Colors.White
            EntryBox.TextColor = Colors.Black
            EntryBox.TextSize = 12
             ' Even if EntryBox is an EditText, EntryBox.Typeface can only be used to set bold, italic etc
            EntryBox.Tag = "Entr"
            EntryBox.Height = 4000dip ' Higher than possible text length initially to make sure text can be measured
           
            For f = 0 To NumOfColumns - 1
                Select f
                    Case 0
                        DtBox.Text = G.TextDate(Row(f))
                    Case 1
                        WthrBox.Text = Row(f)
                    Case 2
                        EntryBox.Text = Row(f)
                        ' The line below is evidently not measuring the text height correctly,
                        ' even when the size is at its default
                        EntryHeight = SU.MeasureMultiLineTextHeight(EntryBox, EntryBox.Text) * 1.5
                        'If EntryHeight > 1500 Then EntryHeight = EntryHeight + 2000
                        ' EntryHeight doesn't expand when the above is added
                        'EntryBox.Text = "*** This box's height should be " & EntryHeight & " " & Row(f)
                        ' PanelHeight below doesn't size bottom margin correctly
                        PanelHeight = EntryHeight + 100dip
                    Case 3 'Travelling
                        If Row(f).Trim = "" Then Place = "" Else Place = " ...Travelling: " & Row(f).Trim
                End Select
            Next 'f
            EntryBox.Height = EntryHeight
            EntryBox.Text = EntryBox.Text & Place & " (END)"
            PanelTop = PanelTop + PanelHeight + 1dip
        Next ' i = Hit
        End If   
        pnlScroll.Height = PanelTop ' Height of OUTER panel
    Catch
        Msgbox ("Error executing query: " & LastException, G.AppName)
    End Try
    G.SQL1.EndTransaction   
End Sub
 
Last edited:

klaus

Expert
Licensed User
Longtime User
...based on an example by Klaus?
What example are you refering to?
I don't see the Scrollview in your code !
Where do you set the Scrollview internal panel height ?
What is pnlScroll ?
What is InnerPnl for ?
Why do you initialize G.SQL1.Initialize(G.DBFileDir, G.DBFileName, True) every time you call the routine, it should be initialized once in the project.
Could you post a small project showing the problem ?
 
Upvote 0

TyneBridges

Member
Licensed User
Longtime User
Thanks for your interest, Klaus. I should have posted my declarations as well. As I remember it, your original example had pnl0 and pnl1 - I substituted the names pnlScroll and InnerPnl. I basically created the whole thing by following your example, without properly understanding it, and I think an InnerPnl is required to display each entry from the database within my outer For..Next loop (I). My aim was to initialise the SQL instance once within the activity - I'm not sure where else it should go.

I must admit I don't know how to post a project without posting the complete code. Apologies for the lack of indents in the code - they all disappeared when I copied it. I thought the forum had a special way to insert code to preserve indentations, but I don't see how to do it.

B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim OurQuery As String
    Dim NumOfColumns As Int: NumOfColumns = 4
    Dim NumOfRows As Int
    Dim RowHeight As Int: RowHeight = 100dip
    Dim RowLineWidth As Int: RowLineWidth = 1dip
    Dim RowHeight1 As Int: RowHeight1 = RowHeight - RowLineWidth
    Dim ColLineWidth As Int: ColLineWidth = 1dip
    Dim ColWidth(NumOfColumns) As Int
    ColWidth(0) = 60dip
    ColWidth(1) = 150dip
    ColWidth(2) = 300dip
    Dim ColWidth1(NumOfColumns) As Int
    Dim TotalColWidth(NumOfColumns + 1) As Int
    Dim Alignment As Int: Alignment = Gravity.LEFT
    Dim SelectedRow As Int: SelectedRow = -1
    Dim Timer1 As Timer
    Dim scvEntries As ScrollView
    Dim pnlScroll As Panel ' Views should be children of this panel
    Dim HitBox As Label
    Dim btnToggle As Button
    Dim btnSrch As Button
    Dim btnMn As Button
    Dim cnv As Canvas
    Dim SU As StringUtils
End Sub

Sub Activity_Create(FirstTime As Boolean)
    ' This activity doesn't need LoadLayout
    ' Visual elements are initialised below or when needed
    scvEntries.Initialize(100%x) ' Parameter is the height. Change in ScrollView.Panel.Height
       
    ' Params for AddView are VName, Left, Top, Width, Height)
    Activity.AddView(scvEntries, 0,  0, 100%x, 100%y)
   
    AddButtons
    ' Initialise scroll panel. This should be taller than the screen.
    ' Height is the final parameter of AddView
    ' Child views appear on this panel
       
    pnlScroll.Initialize("pnlScroll")
    pnlScroll = scvEntries.panel
    scvEntries.Panel.Color = Colors.DarkGray
    ShowTableInFullView(G.Query)
End Sub
 
Last edited:
Upvote 0

TyneBridges

Member
Licensed User
Longtime User
By the way, your example is the CustomScrollView that includes Migrapolis and Kveldsnytt.
 
Upvote 0

JonPM

Well-Known Member
Licensed User
Longtime User
Use code tags please. You can find them under "Insert" on the post dialog menu
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

TyneBridges

Member
Licensed User
Longtime User
Thanks JonPM and DonManfred. I'll use that feature in all future postings!
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
One problem I see in your code is :
You adjust EntryBox.Height according to the text, but you dont adjust the height of InnerPnl which is the container of EntryBox !?
It seems that you have an empty area or 60dip at the top of InnerPnl. do you really want this ?
It would be easier to check the problem with a small project so we could test it.
 
Upvote 0

TyneBridges

Member
Licensed User
Longtime User
You could also edit your actual postings here and add the code new in the right way :D

Done. Thanks to you and Klaus for the help. Will get back when I've looked at Klaus' hints.
 
Upvote 0

TyneBridges

Member
Licensed User
Longtime User
I've managed to create a test project as suggested. I think the attached shows the multiple problems I'm having. What I want it to do is to show text of random different lengths in a box that resizes to the length of each text block.

EntryHeight = SU.MeasureMultiLineTextHeight(EntryBox, EntryBox.Text)
EntryBox.Height = EntryHeight

(In my original app, the text comes from a SQLite database and its length can vary considerably.) Instead, the sizing of the box (EntryBox) seems random, as does the margin below it. In this test project it looks as if the box is always too short whereas, in my original using basically the same code, it was sometimes too short but often about right.

Obviously I haven't properly understood the concepts of a scrollview. (In my original example I did want a margin of 60dip at the top to leave room for some static buttons.) Any corrections would be great to help increase my poor understanding.
 

Attachments

  • Mess.zip
    7.3 KB · Views: 249
Last edited:
Upvote 0

TyneBridges

Member
Licensed User
Longtime User
I've looked at my example in Mess.zip again over the past week and still don't get it.

I set InnerPnl.Height to the sum of the height of the two views contained in it, plus 10dip. I set EntryBox.Height (the larger of the two views above) to the height given in MeasureMultiLineTextHeight. Both InnerPnl and EntryBox do vary in size from entry to entry, but are hardly ever large enough.

Any thoughts?

Thanks.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Several mistakes with the heights in your code.
Attached a modified version.
MeasureMultiLineTextHeight doesn't take into account the padding, so I set EntryBox.Width to 100%x - 10dip for the padding.
And after changing the padding I set EntryBox.Width to 100%x.
 

Attachments

  • Mess1.zip
    7.4 KB · Views: 251
Upvote 0

TyneBridges

Member
Licensed User
Longtime User
Thanks, Klaus! I can see this example is working fine now. I just need to apply the same principles to my original project and it should be fixed too. Vielen Dank.
 
Upvote 0
Top