Android Question Add layout or views n times to panel

Mostez

Well-Known Member
Licensed User
Longtime User
I want to add attached layout to panel n times, then load this panel into 'customlistview'
labels text is loaded from B4Xdatatable, n is equal to the number of columns in datarow, and I want to display one datarow in panel. then repeats for the rest of datarows
the main problem is how to add layout or views n times to panel?

for example if data row have columns, Name, Age, PhoneNumber with data , Any Name, 33, 1234567 I want to display them in the same panel, like

Name
Any Name

Age
33

PhoneNumber
1234567

TIA
 

Attachments

  • Image1.jpg
    Image1.jpg
    8.4 KB · Views: 155

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
The same way you add one panel, with LoadLayout.
  1. Create the panel you'll place in the listview
  2. Load the layout to the new panel
  3. Fill layout with your data
  4. Save any control references to another list or array if you want to
  5. Add panel to listview
  6. Go back to step 1 N Times.
Or am I misunderstanding your question?
 
Upvote 0

Mostez

Well-Known Member
Licensed User
Longtime User
adding the panel to listview is not the problem, the problem is, adding labels to the panel n times like
B4X:
For Each colName As String In Rs.Columns.Keys
Dim ColVal As Object = Row(colIndex)
dim title as label
dim description as label

  panel.add (title)
  panel.add (description)
  title.text = colName 
  description.text =ColVal 
next
 
Upvote 0

josejad

Expert
Licensed User
Longtime User
Hi:

You could adapt this example to your needs, changing "Activity.LoadLayout" with "Panel.LoadLayout"

I'm not sure if you want to load in every CustomListView panel a panel with a lot of labels... or if you want just your layout (the 3 labels) in every CustomListView panel.
 
Upvote 0

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
It seems that you answered your own question, so I'm still confused.... Are you asking how to use a layout instead of manually instantiating the labels?

Instead of diming a label, just use panel.loadlayout(mylayout). Your global variables now reference the ones you just loaded. After the load, just use "lblRowTitle.Text = colName".

I would also recommend setting the btnSelection.Tag property to your colIndex/Name so you can tell which panel was clicked in your event handler.
 
Upvote 0

Mostez

Well-Known Member
Licensed User
Longtime User
this code works ok to add labels to panel multiple times, but I suffered to calculate the position of each view (labels, buttons) also it is not easy to add more views to panel this way, the result is not that good as expected. I wish I can find easier way to add the layout n times to the same panel.

in image 3, user long click the row to start row details activity, he/she can select -show one field of data table in one separate row of custom list view(image2), or view all fields in one row of custom list view(image1)

B4X:
Private Sub ListByRecord()

    lstRowBrowser.Clear
    Dim DataRow As Map = BrowsedTable.GetRow(RowIndex)
    Dim drs As Int = DataRow.Size
    Dim ts As Int = BrowsedTable.Size
    Activity.Title = "Row Details: " & (RowIndex) & " of " & ts
    Dim TlabelHeight As Int = 35 'title label height
    Dim DlabelHeight As Int = 40 'description label height
    Dim LabelsSpaceOffset As Int = 4 'space
    Dim TlabelFirstTop As Int = 2 'title label first top position
    Dim DLabelFirstTop As Int = TlabelFirstTop + TlabelHeight + 1  'description label first top position
    
    Dim ButtonHeight As Int = 48
    Dim ButtonWidth As Int = 48
    'Dim ButtonSpaceOffset As Int = 20
    Dim ButtonFirstTop As Int = 14
    
    Dim p As Panel
    p.Initialize("")
    Activity.AddView(p, 0, 0, 100%x, drs * (TlabelHeight + DlabelHeight + 2)) 'height for total number of labels heights
    'p.LoadLayout("CLVrow")
    p.RemoveView
    p.Color = Colors.White
    
    For Col = 0 To drs -1
        
        Dim plblRowTitle As Label = CreateLable("lblRowTitle",Colors.White,0xFF7A7A7A,14)
        Dim plblDescription As Label  = CreateLable("lblDescription", Colors.White,0xFF000000,15)
        Dim bButton As Button = CreateButton
        
        Dim myCol As B4XTableColumn = BrowsedTable.Columns.Get(Col)
        Dim colname As String = myCol.Title
        Dim Value As Object = DataRow.GetValueAt(Col)
        If Value =  Null Then Value = ""
        
        linkifyTextView(plblDescription,15)
        plblRowTitle.Text = colname
        plblDescription.Text = Value
    
        Dim tTop As Int
        Dim dTop As Int
        Dim bTop As Int
        
        If Col = 0 Then
            tTop  = TlabelFirstTop
            dTop = DLabelFirstTop
            bTop = ButtonFirstTop
        Else
            tTop = Col * (TlabelHeight + DlabelHeight)  + LabelsSpaceOffset + TlabelFirstTop
            dTop = Col * (TlabelHeight + DlabelHeight)  + LabelsSpaceOffset + DLabelFirstTop
            bTop = tTop + (TlabelHeight / 2)'Col * (ButtonHeight) + ButtonSpaceOffset + ButtonFirstTop
        End If
    
        p.AddView(plblRowTitle,4,tTop,90%y,TlabelHeight)
        p.AddView(plblDescription,4,dTop,90%y,DlabelHeight)
        p.AddView(bButton,50%y + 10,bTop,ButtonWidth,ButtonHeight)
        Log (bTop)
    Next
    
    lstRowBrowser.Add(p,"")
End Sub

B4X:
Sub CreateLable(Event As String ,lColor As Int, TextColor As Int,TextSize As Int ) As Label
    Dim NewLabel As Label
    NewLabel.Initialize(Event)
    NewLabel.Text = ""
    NewLabel.SingleLine = True
    NewLabel.Color = lColor
    NewLabel.TextColor = TextColor
    NewLabel.TextSize = TextSize
    NewLabel.Ellipsize = ("END")
    NewLabel.Gravity = Bit.Or(Gravity.LEFT, Gravity.CENTER_VERTICAL)
    Return NewLabel
End Sub
 

Attachments

  • Screenshot_20210811-125904.png
    Screenshot_20210811-125904.png
    38.2 KB · Views: 144
  • Screenshot_20210811-130020.png
    Screenshot_20210811-130020.png
    40 KB · Views: 139
  • Screenshot_20210811-130102.png
    Screenshot_20210811-130102.png
    59 KB · Views: 147
Upvote 0

Mahares

Expert
Licensed User
Longtime User
I wish I can find easier way to add the layout n times to the same panel.
Since essentially you are iterating over a B4Xtable records and displaying them on an xClv, why don’t you use the list that the B4XTable was created from instead of iterating over the table rows. The data in the list can then be used to populate the xClv. The ‘item’ layout of the xClv would have the header for each column and it will have the actual data as labels from the list which is essentially the data on the B4XTable. See screenshots for B4XTable data and corresponding xClv output for a table with 3 columns as an example.
 

Attachments

  • B4XTableScreenshot.png
    B4XTableScreenshot.png
    20.8 KB · Views: 112
  • xClvScreenshot.png
    xClvScreenshot.png
    19.9 KB · Views: 108
Upvote 0

Mostez

Well-Known Member
Licensed User
Longtime User
Thanks everyone for help, I did it as follows
I've created a parent panel to hold the layout n times, the layout is first added to a child panel (temp panel) one time, then we add the child to the parent.
this code reads data of one data row, it should be called m times ( m = number of rows to be listed)
I don't have to design layout for each data table, just the same code and one layout for any datatable.

B4X:
Dim DataRow As Map = BrowsedTable.GetRow(RowIndex)
Dim drs As Int = DataRow.Size
Dim HeightNeeded As Int = (drs * PANEL_HEIGHT) 'panel height, is the height of single layout
Dim pParent As Panel 'this panel will host layout n times
pParent.Initialize("")
pParent.Color = Colors.White
Activity.AddView(pParent, 0, 0, 100%x, HeightNeeded) 'height for total number of panels height

B4X:
'loop data row to get col names and values
    For Col = 0 To drs -1
        Dim myCol As B4XTableColumn = BrowsedTable.Columns.Get(Col)
        Dim colname As String = myCol.Title
        Dim Value As Object = DataRow.GetValueAt(Col)
        If Value =  Null Then Value = ""
        
        Dim rd As CLVrowData
        rd.Initialize
        rd.Description = Value
        rd.RowTitle = colname
        Dim pChild As Panel 'the child panel or temp panel will hold the layout one time
        
        Dim oBm As Object = GetIconByFieldName(colname)
        If oBm <> Null And Value <> "" Then
            rd.Icon = oBm
            pChild = (CreateListItem(rd,False, lstRowBrowser.AsView.Width, PANEL_HEIGHT))
        Else
            'no need to set rd.icon as long as it will be hidden
            pChild = (CreateListItem(rd,True, lstRowBrowser.AsView.Width, PANEL_HEIGHT))
        End If
    
        pParent.RemoveView
        pParent.AddView(pChild,0, Col * PANEL_HEIGHT ,100%x,PANEL_HEIGHT) ' add the child or temp panel to parent
        
    Next
    'now add the parent to CLV
    lstRowBrowser.Add(pParent,RowIndex) 'store row index, will be needed in list view click event
 

Attachments

  • 2rows.png
    2rows.png
    40.4 KB · Views: 90
  • 3rows.png
    3rows.png
    40.9 KB · Views: 87
Upvote 0

josejad

Expert
Licensed User
Longtime User
I'm not sure if you want to load in every CustomListView panel a panel with a lot of labels... or if you want just your layout (the 3 labels) in every CustomListView panel.
That's why I asked this, I was not sure if you really wanted in every single row of the xCLV a lot of panels, or you were trying to "emulate" the behaviour of a xCLV
 
Upvote 0

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
Take a look at this thread and example


The sample app at the end shows how to add multiple items at runtime to a CLV.
 
Upvote 0
Top