B4J Question B4XRadioButton in xCustomListView problem

doncx

Active Member
Licensed User
Longtime User
I have built an xCustomListView for a cross-platform B4XPages project. This is my first shot at cross-plaform, and also xCustomListView though I've worked with B4A for a number of years.

For the life of me I cannot figure out how to address the RadioButton in the List Items. I have tried many things and am not getting anywhere.

In the attached example (clvTest) you'll see that each item has a B4XRadioButton. I'd like to iterate through the items to accomplish several things:

1 - check the radio button when the list item is clicked (and uncheck the other radio buttons)
2 - change the border of the list item when the radio button is checked

I'm having zero success in both B4J and B4A. I've tried accessing it with dd.GetViewByName and also (view).getView(i).

Eventually this needs to work in B4i as well.

Any help would be greatly appreciated.

Many thanks.
 

Attachments

  • clvTest.zip
    352 KB · Views: 130
Solution
This should do the trick.

I save the radio button in the clv directly.

B4X:
    clvExample.Add(CreateListItem( "Item one (index 0)", "img1.jpg" ), CreateMap("data":"one","rb":rdoItem))

then
get this (and its parent) when the clv is clicked
B4X:
Private Sub clvExample_ItemClick(Index As Int, Value As Object)
    Private valmap As Map = Value
    Log(Index & " = " & valmap.Get("data"))
   
    Dim rdo As B4XRadioButton = valmap.Get("rb")

    If(prevrb <> Null And prevrb.IsInitialized) Then
        Private p2 As B4XView = prevrb.mBase.parent
        p2.SetColorAndBorder( xui.Color_RGB( 241, 215, 177 ), 2dip, xui.Color_RGB(255, 255, 255), 6dip)
'        prevrb.Checked = False
    End If
        Dim p2 As B4XView = rdo.mBase.Parent...

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
This should do the trick.

I save the radio button in the clv directly.

B4X:
    clvExample.Add(CreateListItem( "Item one (index 0)", "img1.jpg" ), CreateMap("data":"one","rb":rdoItem))

then
get this (and its parent) when the clv is clicked
B4X:
Private Sub clvExample_ItemClick(Index As Int, Value As Object)
    Private valmap As Map = Value
    Log(Index & " = " & valmap.Get("data"))
   
    Dim rdo As B4XRadioButton = valmap.Get("rb")

    If(prevrb <> Null And prevrb.IsInitialized) Then
        Private p2 As B4XView = prevrb.mBase.parent
        p2.SetColorAndBorder( xui.Color_RGB( 241, 215, 177 ), 2dip, xui.Color_RGB(255, 255, 255), 6dip)
'        prevrb.Checked = False
    End If
        Dim p2 As B4XView = rdo.mBase.Parent
        p2.SetColorAndBorder( xui.Color_RGB( 241, 215, 177 ), 2dip, xui.Color_RGB(210, 0, 35), 6dip)
        prevrb = rdo
'        rdo.Checked = True
End Sub

Note: If click on the radio button directly then the panel will not highlight. But it is straighforward to add this functionality.

This should work without any changes on B4i. I only had an android phone to hand so couldn't check.
 

Attachments

  • clvTestnew.zip
    352 KB · Views: 154
Upvote 0
Solution

doncx

Active Member
Licensed User
Longtime User
Thanks for the education, Andrew!

I'm still parsing out exactly how/why that works, but it works. I'm sure it'll become clear with a bit more study.

Again, many thanks.
 
Upvote 0

doncx

Active Member
Licensed User
Longtime User
Andrew, I understand your strategy for processing clicks on items. It points out how little I've understood about xCustomListViews and their listitems. I've watched videos and read dozens of forum posts, still finding myself somewhat mystified by some of the associations.

I'm still unable to figure out how to address the second need; to intercept and handle a click on one of the radio buttons. With Andrew's help I now see how to set them, but how do I detect clicks on them?

Also, If there's any learning materials, posts, or tutorials that might assist me with this please point me in that direction.

Many thanks
 
Upvote 0

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
hi @doncx ,

You would need to trap the radio button click event.

The key is that ALL radio buttons will activate the same click event.

B4X:
private Sub rdoItem_Checked
 
    Log("Clicked on radio button")
    ' Get the actual Radio button clicked
    Private rb As B4XRadioButton = Sender

   ' only do this if selecting not unselecting - Can cause infinite loops
    If (rb.Checked) Then      
        If (prevrb <> Null And prevrb.IsInitialized) Then
            prevrb.Checked = False
        End If
  
        ' Get the clc row from for the radio button
        Private index As Int = clvExample.GetItemFromView(rb.mBase)
  
        Log($"Clicked on ${index} clv item"$)
  
        ' Simulate click on row
        clvExample_ItemClick(index,clvExample.GetValue(index))
    End If
End Sub

Edited to add comments
 
Upvote 0

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
Custom List Views are very flexible and this can make them a bit hard to wrap your head around.

I agree that a tutorial to show a general example of this would be very useful. There may be one on the forums somewhere.
 
Upvote 0

doncx

Active Member
Licensed User
Longtime User
Andrew - I was figuring this out just as you posted above. My code looks remarkably like your post! It makes sense. I get it.

Indeed, wrapping my head around Custom List Views is a project! Much more learning ahead.

Great Thanks for your assistance. It has been very, very helpful.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
'm having zero success in both B4J and B4A.

Here is a different approach to that of the great DigitWell work. This is for your B4J project you posted in post #1 because the layout you have for the B4A project is different. I can post you the B4A sub if you want. If you replace your sub with this corresponding one in your B4J project, you will get what you wanted to achieve:
B4X:
    'For the B4J clvItemlayout. Please note this is for when you click an item as you wanted not the radio button
Private Sub clvExample_ItemClick(Index As Int, Value As Object)
    For i=0 To clvExample.Size-1
        Dim p As B4XView=clvExample.GetPanel(i)
        'for XUI Views the view is stored in its tag as designed byErel
        Dim rx As B4XRadioButton = clvExample.GetPanel(i).GetView(2).Tag '3rd view See designer tree hierarchy
        Dim ivx As B4XImageView =clvExample.GetPanel(i).GetView(1).Tag   'Second view . See designer
        If i =Index Then
            p.SetColorAndBorder( xui.Color_RGB( 241, 215, 177 ), 6dip, xui.Color_RGB(210, 0, 35), 6dip)
            If rx.Checked = False Then
                rx.Checked = True
                ivx.RoundedImage=True      'added . You don't have to have it
            End If
        Else
            p.SetColorAndBorder( xui.Color_transparent, 0dip, xui.Color_transparent, 0dip)
            rx.Checked = False
            ivx.RoundedImage=False       'added . You don't have to have it
        End If
    Next
End Sub
 
Upvote 0

doncx

Active Member
Licensed User
Longtime User
Thank you Mahares. Your example demonstrates the use of .Tag, which is what I was missing in my early attempts. I found the RadioButton view, but when addressed it errored as "uninitialized". I didn't understand the use of Tag.

Thank you for showing this method. Very helpful as well.
 
Upvote 0
Top