B4J Question Exposing Items In B4J Custom List View (Solved)

RichardN

Well-Known Member
Licensed User
Longtime User
Having used CustomListView in both B4A and B4i I thought I knew how to do this......

A CLV cell has an Image and a Label loaded from a layout... so far so good. Unfortunately I am unable to access any view property from a clicked cell. Something appears to be different in B4J which I am totally missing. What code is required in the CLV click event to explore the views contained within in it?

B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI
    
    Private imgThumbnail As B4XView
    Private lblCountry As B4XView
    Private clvCountries As CustomListView
    
    Private SQL As SQL

End Sub

Sub AppStart (Form1 As Form, Args() As String)
    
    SQL.InitializeSQLite(GetEnvironmentVariable("DataDir",""),"Flags.db3",False)
    
    MainForm = Form1
    MainForm.RootPane.LoadLayout("main")
    MainForm.Title = "World Flags"
    MainForm.Show
    
    Dim rs As ResultSet = SQL.ExecQuery("SELECT * FROM ISO2 ORDER BY Country")
    Dim DefaultHeight As Int = 65dip
    
    Do While rs.NextRow
        
        Dim Buffer() As Byte
        Buffer = rs.GetBlob("Thumbnail")
    
        Dim InputStream1 As InputStream
        InputStream1.InitializeFromBytesArray(Buffer, 0, Buffer.Length)
    
        Dim bmp As Image
        bmp.Initialize2(InputStream1)
        
        Dim p As B4XView = xui.CreatePanel("")
        p.Tag = rs.GetString("ISO2code")
        
        p.SetLayoutAnimated(0, 0, 0,clvCountries.AsView.Width, DefaultHeight)
        p.LoadLayout("clvItem")
    
        ImgThumbnail.SetBitmap(bmp)
        lblCountry.Text = rs.GetString("Country")
            
        clvCountries.Add(p,"")
        
    Loop
    
End Sub

Sub clvCountries_ItemClick (Index As Int, Value As Object)
    
    Log("This event fires every time as expected")
    'What code is required here to expose the cell tag property and lblCountry.Text?
    
End Sub
 
Solution
@aeric...
I populate each cell with a label string and a bitmap image. I set the Tag property of the xui panel to a string before adding it to the CLV.

When the clvCountries_ItemClick event fires the Index value is correct but the Value appears to return nothing.
As I written, you need to pass the value in second parameter. You were passing an empty String.

Your code:
B4X:
clvCountries.Add(p, "")
My code:
B4X:
clvCountries.Add(p, Value)

You don't need to use Tag.

RichardN

Well-Known Member
Licensed User
Longtime User
@aeric...
I populate each cell with a label string and a bitmap image. I set the Tag property of the xui panel to a string before adding it to the CLV.

When the clvCountries_ItemClick event fires the Index value is correct but the Value appears to return nothing.
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
@aeric...
I populate each cell with a label string and a bitmap image. I set the Tag property of the xui panel to a string before adding it to the CLV.

When the clvCountries_ItemClick event fires the Index value is correct but the Value appears to return nothing.
As I written, you need to pass the value in second parameter. You were passing an empty String.

Your code:
B4X:
clvCountries.Add(p, "")
My code:
B4X:
clvCountries.Add(p, Value)

You don't need to use Tag.
 
Upvote 0
Solution

RichardN

Well-Known Member
Licensed User
Longtime User
Thanks @aeric I see what you mean now..... your solution works and it fixes my immediate problem.

However my question remains: If I wanted to read the property of a view within a panel, (not set by your method) within a CSV cell, how is it done in B4J ?
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
Thanks @aeric I see what you mean now..... your solution works and it fixes my immediate problem.

However my question remains: If I wanted to read the property of a view within a panel, (not set by your method) within a CSV cell, how is it done in B4J ?
You mean user clicked on label or the panel?
You want to get the value of Text of a label?
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
There are many examples on the forum but I only can think of this.

Something like this :
B4X:
Sub LblEdit_Click
    Dim index As Int = CLV.GetItemFromView(Sender)
    Dim pnl As B4XView = CLV.GetPanel(index) ' ListItem
    Dim pan As B4XView = pnl.GetView(0)        ' PnlItem
    Dim lbl As B4XView = pan.GetView(1)        ' LblText
   ' the rest of code
End Sub
 
Upvote 0

RichardN

Well-Known Member
Licensed User
Longtime User
B4X:
Sub clvCountries_ItemClick (Index As Int, Value As Object)
  
    Dim cell As B4XView = clvCountries.GetPanel(Index)  'This is a cell of a CLV List
  
    Dim img As ImageView = cell.GetView(0)          'Happens to be an image
    Dim lbl As B4XView = cell.GetView(1)                'Happens to be a label
  
    Log(img.Width)
    Log(lbl.Text)
  
End Sub

I guess it is super important to remember what sort of object was added to the CLV cell in the first place, and retrieve that object into the correct type of variable, and in the correct order.... That was my mistake, confusing the parent B4Xview with a normal panel. Thanks @aeric
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
B4X:
Sub clvCountries_ItemClick (Index As Int, Value As Object)
 
    Dim cell As B4XView = clvCountries.GetPanel(Index)  'This is a cell of a CLV List
 
    Dim img As ImageView = cell.GetView(0)          'Happens to be an image
    Dim lbl As B4XView = cell.GetView(1)                'Happens to be a label
 
    Log(img.Width)
    Log(lbl.Text)
 
End Sub

I guess it is super important to remember what sort of object was added to the CLV cell in the first place, and retrieve that object into the correct type of variable, and in the correct order.... That was my mistake, confusing the parent B4Xview with a normal panel. Thanks @aeric
You can get the order and type of views from your layout Views Tree.
In case you want to do something different when clicking on the Label or on the Image (or everything else) then you have to create the Click event for every single view and use the Sender to get the calling view.
 
Upvote 0
Top