iOS Question Horizontal CustomListView as an Element in a Vertical CustomListView

Marcos Alves

Well-Known Member
Licensed User
Hello,

I need to add a horizontal CustomListView as an element of a Vertical CLV. The code that I'm using is:

B4X:
Private Sub createOfertas As B4XView
    
    Dim p As B4XView = xui.CreatePanel("")
    p.SetLayoutAnimated(0,0,0,100%x,200dip)
    p.LoadLayout("restaurantMenuOfertas")
    Dim clvOfertas As CustomListView = p.GetView(0)
    
    Dim query As String = "select * from cadProd where idRest = " & idRest & " and unitOriginalPrice > 0  and unitPrice > 0 order by (unitPrice - UnitOriginalPrice) asc limit 4"
    Dim cursor1 As ResultSet
    cursor1 = B4XPages.MainPage.sql1.ExecQuery(query)
    Do While cursor1.NextRow
        clvOfertas.Add(createOfertasItens,"ofertas")
    Loop
    
    cursor1.Close
    Return p
    
End Sub

Private Sub createOfertasItens As B4XView
    
    Dim p As B4XView = xui.CreatePanel("")
    p.SetLayoutAnimated(0,0,0,100%x,200dip)
    p.LoadLayout("restaurantMenuOfertaItem")
    
    p.Width = 80dip
    p.Height = 200dip
    
    Return p           <---- Error here
    
End Sub

But when I try to the individual rows in the horizontal CLV I'm getting the error:

B4X:
Method not found: _add::, target: <B4IPanelView: 0x103b1b3d0; frame = (0 0; 375 181.973); clipsToBounds = YES; animations = { bounds.origin=<CASpringAnimation: 0x282c22480>; bounds.size=<CASpringAnimation: 0x282c22440>; position=<CASpringAnimation: 0x282c22380>; }; layer = <CALayer: 0x282c22360>>

It isn't possible to load an horizontal CLV as an item inside a vertical CLV? What's the correct method?

Thanks!

PS: the parent CLV is being loaded in the root panel, in the first layout... the second is loaded in the item layout of the first (CLVOfertas in layout restaurantMenuOfertas, item 0)
 

Marcos Alves

Well-Known Member
Licensed User
You really should learn how to use parameterized queries.

The problem is here.



Read this: https://www.b4x.com/android/forum/t...om-clv-or-any-other-container.117992/#content
Hello @Erel , I've already read this but really didn't find a way to reference a CLV inside a panel in another CLV. See:

- In the example, the CLV is in the main parent panel and it's explained how to reference this after :

B4X:
clv.AsView.Tag = clv
'now we can get the clv with:
Dim c As CustomListView = Activity.GetView(<clv index>).Tag

I already tried to declare the second CLV as a Class global view but didn't work also:

B4X:
Sub Class_Globals

    Private CLV1 As CustomListView
    Private CLV2 As CustomListView
    
End Sub
...
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    'load the layout to Root
    Root.LoadLayout("restaurantMenuLayout") <--- CLV1 is loaded here
    
    CLV2.initialize("CLV2","")
    CLV2.AsView.Tag = CLV2 <----   Error(?) - This will not reference CLV2 Really because it isn't instantiated yet (I think)
    
    CLV1.Add(createOfertas,"ofertas")
    
End Sub

Private Sub createOfertas As B4XView
    
    Dim p As B4XView = xui.CreatePanel("")
    p.SetLayoutAnimated(0,0,0,100%x,200dip)
    p.LoadLayout("restaurantMenuOfertas")
    Dim clvPanel As CustomListView = p.GetView(0).tag
    clvPanel.Add(createOfertasItens,"ofertas")
    Return p

End Sub

Private Sub createOfertasItens As B4XView
    
    Dim p As B4XView = xui.CreatePanel("")
    p.SetLayoutAnimated(0,0,0,100%x,200dip)
    p.LoadLayout("restaurantMenuOfertaItem") <--- Here is a design with CLV2 only (index 0)
    
    p.Width = 80dip
    p.Height = 200dip
    
    Return p
    
End Sub

I really have no more ideas ... I understood the problem - custom list view is a Class,it isn't really a view, and it isn't possible to getview it directly. But I cant' imagine a manner to recover it with a getview inside another CLV panel.
Is it possible @Erel ?

Thanks!
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
You really should learn how to use parameterized queries.

The problem is here.



Read this: https://www.b4x.com/android/forum/t...om-clv-or-any-other-container.117992/#content
Hello @Erel ,

as always, you inspired me 👏
The problem:
- I have two CLV, let's say: CLV1 and CLV 2
- I tried to load the layout containing CLV2 in a panel in CLV1 and, IN createPanel routine of CLV1, call createPanel in CLV2 also. This is the problem: the panel in CLV1 containing CLV2 isn't created yet before "return p"... As CLV is a CLASS, CLV2 isn't instatiated yet and cannot run the method add. Then, trying to add panels in CLV2 inside the routine that loads itself in CLV1 is an error.
What did I do:

- Defined CLV2 also as a class Global customview with an unique name (then I don't need to worry about referencing later with a tag, getview... as described here )
- Loaded the design containing CLV2 with a createpanel routine in CLV1... in this routine I don't try to create the panels in CLV2
- AFTER CreatePanel in CLV1 finishes, then add panels in CLV2 (outisde this routine)

The code is something like Ths:

B4X:
Sub Class_Globals

    Private CLV1 As CustomListView
    Private CLV2 As CustomListView <--- This CLV will be in an item in CLV1
    
End Sub
...
Public Sub createPage(idRestCreate As Long)
...
        CLV1.Add(createOfertas,"ofertas")
        
        '### Here the Class CLV2 is instantiated and ready to receive items
        query = "select * from sample"
        cursor2 = B4XPages.MainPage.sql1.ExecQuery(query)
        Do While cursor2.NextRow
            CLVOfertas.Add(createOfertasItens,"ofertas")
        Loop
        cursor2.Close

End Sub

Private Sub createOfertas As B4XView
    
    Dim p As B4XView = xui.CreatePanel("")
    p.SetLayoutAnimated(0,0,0,100%x,200dip)
    p.LoadLayout("restaurantMenuOfertas") <--- This design contains CLV2
    
    Return p
    
End Sub

Private Sub createOfertasItens As B4XView
    
    Dim p As B4XView = xui.CreatePanel("")
    p.SetLayoutAnimated(0,0,0,100%x,200dip)
    p.LoadLayout("restaurantMenuOfertaItem") <--- This design contains each item in CLV2
    
    p.Width = 80dip
    p.Height = 200dip
    
    Return p
    
End Sub

That's it! I think that using the method described by @Erel in the thread that he referenced you can avoid the need for registering CLV2 as a global class object and opens the possibility to dynamically create many copies in many items inside a "parent" clv1, referencing those later with getview using tags, but I didn't tested this.
I hope that this thread could be useful to community.

Thanks @Erel !!!
 
Upvote 0

Marcos Alves

Well-Known Member
Licensed User
You really should learn how to use parameterized queries.
😂 leave me with my queries 😂
Now seriously: do you know what is the problem of parametrized queries (at least for me)? I have a copy of all databases that I use in PC and sometimes, when I have a more complicated query and get an error, with a unparametrized query I only go to app log and copy, then pasting it into database framework to test and debug easily . I know that I only need to do this in complicated queries with lots of "joins" and indexes but... at the end of the day accustomed to do this. I know that I could have problems with special characters inside the query that could raise an error using standard non parametrized calls but... we have habits... I'm a near 50 years old programmer... to change is hard 😂
Thanks for the tip @Erel . I'll try hard to use parametrized queries.
 
Last edited:
Upvote 0
Top