B4J Question How to find a Label inside a CustomListView-Item?

Midimaster

Active Member
Licensed User
I have a CustomListView with 20 items. Each item was made by loading the same Layout. The Layout is a pane that contains panes, and labels. In this moment also the text of the label was added.

Now I want to change the textcolor of the label StudioSpurItem of item X. How can I do this?

1603119206599.png


B4X:
Sub Process_Globals
    Private  StudioSpurItem, Dragger As B4XView
    Private UpLbl, DownLbl, OpenLbl, MetroLbl, Muell As Label
...

Sub AppStart (Form1 As Form, Args() As String)
    mCLV.Initialize("")
    For i = 0 To 20
        Dim pnl As B4XView = CreateItem("Zeile" & i)
        mCLV.Add(pnl,i)
    Next
...   
    
Sub CreateItem(Title As String) As B4XView
    Dim p As B4XView = xui.CreatePanel("")
    p.LoadLayout("Item")
    p.SetLayoutAnimated(0, 0, 0, p.Width, p.Height)
    StudioSpurItem.Text = Title
    Return p
End Sub

So the questions is: How to iterate through the views of a CustomListView. At the moment each attempt ends with a casting problem:
B4X:
Sub Search(index As Int)
    Dim pnl As B4XView = mCLV.GetPanel(index).Parent
    'For Each v As B4XView  In pnl.GetAllViewsRecursive
    For Each v As Label  In pnl.GetAllViewsRecursive
            Log("iterate=" & v.text)
    Next
End Sub
 

stevel05

Expert
Licensed User
Longtime User
As you know which view on the Base panel you want to change, it is straightforward to change them directly.

B4X:
 Dim pnl As B4XView = mCLV.GetPanel(index).Parent
pnl.GetView(0).TextColor = xui.Color_Blue

Assuming the label is the first view in the views tree of the layout.
 
Upvote 0

Midimaster

Active Member
Licensed User
More generic:

Yes I also found a read the article before , but I did not understand, how I can use it for my problem.

As you know which view on the Base panel you want to change, it is straightforward to change them directly.
But this only works as long as I know the order of the views. Is there no way to iterate through a given view-tree? Lets say to search for a user changed text in one of the views?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
As you have found out, you cannot use Label, or B4xView as the Type of the view to iterate as not all views can be cast to either. But you can use object and check the type

B4X:
 Dim pnl As B4XView = mCLV.GetPanel(index).Parent
    For Each v As Object In pnl.GetAllViewsRecursive
            If V Is Label Then
                Dim B4xV as B4xView = V
                Log("iterate=" & B4xV.text)
            'else If V Is somethingelse Then
                'do whatever
            end If
    Next

Quite a few of the standard views can be cast to B4xView, so it can be useful to test for the know cases that will fail first.

Although using this method you need to differentiate between multiple views of the same type the layout to find the one you want, in which case you can use the Tag field which you should set in the layout designer.

B4X:
[CODE=b4x] Dim pnl As B4XView = mCLV.GetPanel(index).Parent

    For Each v As Object In pnl.GetAllViewsRecursive

            If V Is Label Then

                Dim B4xV as B4xView = V
                If B4xV.Tag = "StudioSpurItem" Then
                    Log("StudiospurItem=" & B4xV.text)
                Else
                    Log("Other Label " & B4xV.text)
                end If
            'else If V Is somethingelse Then

                'do whatever

            end If

    Next
 
Last edited:
Upvote 0

Midimaster

Active Member
Licensed User
Thanks Steve! I posted a solution the same moment with you!!:D

ok I'm a little step ahead:

this would not crash:
B4X:
Sub Search(index As Int)
    Dim pnl As B4XView = mCLV.GetPanel(index).Parent
    For Each v As B4XView  In pnl.GetAllViewsRecursive
        If v Is Label Then
            Log("iterate=" & v.text)
        End If
    Next
End Sub
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
this would not crash:

It will if you have a customview on the pane. There are other views that cannot be cast to a B4xView as well, but I can't remember what they all are.

It would be safer to use Object and test specifically.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Hmm, sorry for the confusion, now I just have to work out what I was confusing it with :)
 
Upvote 0

Midimaster

Active Member
Licensed User
I'm still experimenting with the Iteration through the xCustomListView and have a new question

With the function view.GetAllViewsRecursive I can interate, but in the end I find anything, but cannot say how deep am I in the tree. Also the view seems to have no ID. Is this correct? I only can see, that this object has the text I was looking for:
B4X:
    For Each v As B4XView  In pnl.GetAllViewsRecursive
        If v Is Label Then
            Log("iterate=" & v.text & " ")
        End If
    Next



When I try to interate "manually" I cannot check the very deepest iteration, whether there are children, because already the question view.NumberOfViews causes a crash. Shouldn't it return 0 if there are more children?
B4X:
    Dim pnl As B4XView = mCLV.GetPanel(index).Parent
    Dim lbl As B4XView= pnl.GetView(0)
    Log("views" & lbl.NumberOfViews) 
    Dim lbl As B4XView= pnl.GetView(0).GetView(0)
    Log("views" & lbl.NumberOfViews)
    Dim lbl As B4XView= pnl.GetView(0).GetView(0).GetView(1)
    Log (lbl.text)
    Log("views" & lbl.NumberOfViews)


As a workaround I found the order of my object as:
B4X:
    Dim lbl As B4XView= pnl.GetView(0).GetView(0).GetView(1)
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

Midimaster

Active Member
Licensed User
so i have to add "special" functions which serve only for the current layout. And if i change the layout I again have to change the functions?
B4X:
Sub FindNameLabel(Index As Int) As Label
    Dim pnl As B4XView = mCLV.GetPanel(Index).Parent
    Return pnl.GetView(0).GetView(0).GetView(1)
End Sub


Sub FindMetroButton(Index As Int) As Label
    Dim pnl As B4XView = mCLV.GetPanel(Index).Parent
    Return pnl.GetView(0).GetView(1).GetView(3)
End Sub
wouldn't it helpful for all these actions to add another property UniqueID to the B4XViews, which i can search and identify each element of a layout? Yes I know there is already a tag, but this we often use to point to other things like identify action targets, etc...
 
Upvote 0
Top