Android Question Can one access individual control(i.e Radiobutton) from panel without loosing "group" attribute?

omo

Active Member
Licensed User
Longtime User
Purpose of using panel for radiobutton is to group those radiobuttons together, however; there are times one needs to access one radiobutton from this group for more specific coding purpose, is it possible or is there any technique one can use to reference one single radiobutton from panel without loosing that grouping attribute inherited from panel? I used pnl.Getview(0), dd.GetViewByName(pnl, "RadioButton1") or similar but were found to loose that inherited panel "grouping" attribute. Is there any other way different from above or can i get sample code on how it can be done? For example: If we load 3-radiobuttons from designer into panel (pnl), it will work as group, but once the three buttons are accessed thus:
Dim radiobutton1 as radiobutton = pnl.Getview(0)
Dim radiobutton2 as radiobutton = pnl.Getview(1)
Dim radiobutton3 as radiobutton = pnl.Getview(2)

radiobuton1, 2 and 3 will loose that panel grouping identity which render them unusable in some programming logic solution

or aside using panel to group radiobutton, is there any other ways either via Javacode or other means different from panel that will not loose inherited "group" attribute when accessed individually for further coding?
 
Last edited:

Sagenut

Expert
Licensed User
Longtime User
B4X:
Dim RB as RadioButton = Panel.GetView(X)
RB will be a temporary reference to work with your original RadioButton.
You must know, looking your Views Tree, which number must be X to reference the one you want.
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
B4X:
Dim RB as RadioButton = Panel.GetView(X)
RB will be a temporary reference to work with your original RadioButton.
You must know, looking your Views Tree, which number must be X to reference the one you want.
Thank you @Sagenut; Yes, i knew this, and i worked with it; if you check my other questions posted today on B4Xradiobutton and ASradiobutton, the problem is that once you access any of the radiobutton with Panel.GetView(0) or whatever number on designer tree; it losses its "group" attribute inherited with the panel. My sample codes are there in those refrenced question-threads. If you use that method to access three radio buttons in panel for example and you loop it, you will discover that instead on selecting one in a group of three, all groups in the loop will loose one selection per group. I also went ahead using refrencing via designerscript i.e dd.GetViewByName(pnl, "ASRadioButton1"), but to no avail (same problem). That is why i am asking if there is any other way of achieving this. I have modified that question for more clearity
 
Last edited:
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
I am not in front of PC so I cannot make tests.
Sorry if I misunderstood the question. šŸ˜…
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
Anyway make clear if you are working with RadioButton or with B4XRadioButton.
B4XRadioButton should be a CustomView, so to real view is stored in the Tag property.
Maybe try
B4X:
Dim RB as B4XRadioButton = Panel.GetView(X).Tag
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
I am not in front of PC so I cannot make tests.
Sorry if I misunderstood the question. šŸ˜…
No, no, you never misunderstood it, your response was very very OK and appreciate. It is your response that made me modify that question for more clarity. Thank you
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
Anyway make clear if you are working with RadioButton or with B4XRadioButton.
B4XRadioButton should be a CustomView, so to real view is stored in the Tag property.
Maybe try
B4X:
Dim RB as B4XRadioButton = Panel.GetView(X).Tag
I also tried to end with ".tag", in some cases where ".tag" was permitted, in some other scinerio; i ended with ".mbase or .base"; where these work or reference control itself, they still loose grouping identity of the panel
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
It is easy enough to roll your own radio button action and put all of them into a BBCodeView.

B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private BBCodeView1 As BBCodeView
    Private textEngine1 As BCTextEngine
    Private allOptions As List
    Private busy As Boolean
End Sub

Public Sub Initialize
    allOptions.Initialize
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Dim targetPanel As B4XView = xui.CreatePanel("")     'In case there is other stuff on the page
    Root.AddView(targetPanel, 0, 0, Root.Width, Root.Height)
    textEngine1.Initialize(targetPanel)
    targetPanel.LoadLayout("MainPage")
    BBCodeView1.TextEngine = textEngine1
   
    'Three groups of four radio buttons
    Dim content As StringBuilder: content.Initialize
    Dim texts(4) As String = Array As String("Option 1", $"Line 1${CRLF}Line 2${CRLF}Line 3${CRLF}Line 4${CRLF}Line 5"$, "Option 3", "Option 4")
    For i = 0 To 2
        For j = 0 To 3        'j is button #
            Dim rb As RadioButton
            rb.initialize("RadioBtns")
            BBCodeView1.Views.Put("rb_" & i & "_" & j, rb)
            rb.Tag = Array As Int(i, j)
            content.Append($"[View=rb_${i}_${j} Vertical=3/]"$).Append(CRLF).Append($"[Indent=1]${texts(j)}[Indent=0]"$).Append(CRLF)
            allOptions.Add(rb)
        Next
    Next
    BBCodeView1.Text = content.toString
End Sub

Private Sub RadioBtns_SelectedChange(Selected As Boolean)
    If busy Then Return
    Dim rbx As RadioButton = Sender
    Dim which() As Int = rbx.tag
    If rbx.As(B4XView).Checked Then
        busy = True
        For Each rb As B4XView In allOptions
            Dim wh() As Int = rb.Tag
            If wh(0) = which(0) And wh(1)<>which(1) Then rb.Checked = False
        Next
        busy = False
    End If
End Sub
Screenshot 2023-04-04 180359.jpg
 

Attachments

  • MyRadios.zip
    37.9 KB · Views: 62
  • Like
Reactions: omo
Upvote 0

omo

Active Member
Licensed User
Longtime User
It is easy enough to roll your own radio button action and put all of them into a BBCodeView.

B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private BBCodeView1 As BBCodeView
    Private textEngine1 As BCTextEngine
    Private allOptions As List
    Private busy As Boolean
End Sub

Public Sub Initialize
    allOptions.Initialize
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Dim targetPanel As B4XView = xui.CreatePanel("")     'In case there is other stuff on the page
    Root.AddView(targetPanel, 0, 0, Root.Width, Root.Height)
    textEngine1.Initialize(targetPanel)
    targetPanel.LoadLayout("MainPage")
    BBCodeView1.TextEngine = textEngine1
 
    'Three groups of four radio buttons
    Dim content As StringBuilder: content.Initialize
    Dim texts(4) As String = Array As String("Option 1", $"Line 1${CRLF}Line 2${CRLF}Line 3${CRLF}Line 4${CRLF}Line 5"$, "Option 3", "Option 4")
    For i = 0 To 2
        For j = 0 To 3        'j is button #
            Dim rb As RadioButton
            rb.initialize("RadioBtns")
            BBCodeView1.Views.Put("rb_" & i & "_" & j, rb)
            rb.Tag = Array As Int(i, j)
            content.Append($"[View=rb_${i}_${j} Vertical=3/]"$).Append(CRLF).Append($"[Indent=1]${texts(j)}[Indent=0]"$).Append(CRLF)
            allOptions.Add(rb)
        Next
    Next
    BBCodeView1.Text = content.toString
End Sub

Private Sub RadioBtns_SelectedChange(Selected As Boolean)
    If busy Then Return
    Dim rbx As RadioButton = Sender
    Dim which() As Int = rbx.tag
    If rbx.As(B4XView).Checked Then
        busy = True
        For Each rb As B4XView In allOptions
            Dim wh() As Int = rb.Tag
            If wh(0) = which(0) And wh(1)<>which(1) Then rb.Checked = False
        Next
        busy = False
    End If
End Sub
View attachment 140960
Whaoo! @William Lancee, thank you so much. I have never thought of it this way, neither will my mind even go into this direction. I have not implemented it yet, but merely studying your code snippet, I can understand your trick and I should be able to apply the logic to B4xradiobutton or AS_radiobutton. Thank you so much, once I implement it correctly, I will come here to put solved
Regards
 
Upvote 0

teddybear

Well-Known Member
Licensed User
Dim radiobutton1 as radiobutton = pnl.Getview(0)
Dim radiobutton2 as radiobutton = pnl.Getview(1)
Dim radiobutton3 as radiobutton = pnl.Getview(2)

radiobuton1, 2 and 3 will loose that panel grouping identity which render them unusable in some programming logic solution

or aside using panel to group radiobutton, is there any other ways either via Javacode or other means different from panel that will not loose inherited "group" attribute when accessed individually for further coding?
Before defining these radiobuttonsļ¼Œyou may give a tag to them of the panel first
B4X:
    For i= 0 To Pnl.NumberOfViews -1
        PnlGetView(i).Tag = "Pnl"
    Next
    Dim radiobutton1 as radiobutton = pnl.Getview(0)
    Dim radiobutton2 as radiobutton = pnl.Getview(1)
    Dim radiobutton3 as radiobutton = pnl.Getview(2)
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
Before defining these radiobuttonsļ¼Œyou may give a tag to them of the panel first
B4X:
    For i= 0 To Pnl.NumberOfViews -1
        PnlGetView(i).Tag = "Pnl"
    Next
    Dim radiobutton1 as radiobutton = pnl.Getview(0)
    Dim radiobutton2 as radiobutton = pnl.Getview(1)
    Dim radiobutton3 as radiobutton = pnl.Getview(2)
Ok, I have not tried it out in this way too. Thank you, I will check it out too
 
Upvote 0

sumairtariq212

New Member
Before defining these radiobuttonsļ¼Œyou may give a tag to them of the panel first
B4X:
    For i= 0 To Pnl.NumberOfViews -1
        PnlGetView(i).Tag = "Pnl"
    Next
    Dim radiobutton1 as radiobutton = pnl.Getview(0)
    Dim radiobutton2 as radiobutton = pnl.Getview(1)
    Dim radiobutton3 as radiobutton = pnl.Getview(2)
ok i Tried it
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
Before defining these radiobuttonsļ¼Œyou may give a tag to them of the panel first
B4X:
    For i= 0 To Pnl.NumberOfViews -1
        PnlGetView(i).Tag = "Pnl"
    Next
    Dim radiobutton1 as radiobutton = pnl.Getview(0)
    Dim radiobutton2 as radiobutton = pnl.Getview(1)
    Dim radiobutton3 as radiobutton = pnl.Getview(2)
I tried this but i was getting error, properbly because i didnt do it well. "PnlGetView" is declared as what? B4xview ? I like to see what logical solution this your approach will offer. Please, I wouldn't mind if i can get simple sample code that demostrates this your approach for 2/3 radiobuttons when you get spare time. @William Lancee solution already worked and that of @Erel's solution on another thread, but i like to see this your solution possibility too so i can decide on approach to use at different time
 
Upvote 0

teddybear

Well-Known Member
Licensed User
I tried this but i was getting error, properbly because i didnt do it well. "PnlGetView" is declared as what? B4xview ? I like to see what logical solution this your approach will offer. Please, I wouldn't mind if i can get simple sample code that demostrates this your approach for 2/3 radiobuttons when you get spare time. @William Lancee solution already worked and that of @Erel's solution on another thread, but i like to see this your solution possibility too so i can decide on approach to use at different time

The sample is attached.
 

Attachments

  • GrpRd.zip
    10.2 KB · Views: 59
Upvote 0

omo

Active Member
Licensed User
Longtime User
The sample is attached.
Thank you once again for this. I need this code to be in a loop before i can know if it works or not because only one must be selected in group of three. I copied important segment of code to B4xpages and put it on a loop after modifying it like this:

B4X:
For i = 1 To 4  'number of three groups four times
        
        pnl  = xui.CreatePanel("")
        pnl.SetLayoutAnimated(0, 0, 0, Root.Width, 200dip)
    
        pnl.LoadLayout("RadioButtons")
        
        For k = 0 To  pnl.NumberOfViews -1
            pnl.GetView(k).Tag = "Pnl" & i  ' if i remove & i, i will pnl logged in all 4 x 3 loop          '
       Next
      
        rb11  = pnl.GetView(0)
        rb21  = pnl.GetView(1)
        rb31 = pnl.GetView(2)
        Log(rb11.Tag)
        Log(rb21.Tag)
        Log(rb31.Tag)
next

As log, i got:
Pnl1
Pnl1
Pnl1
Pnl2
Pnl2
Pnl2
Pnl3
Pnl3
Pnl3
Pnl4
Pnl4
Pnl4

NOTE: I applied this loop to B4xradiobutton instead, all 4 x 3 radiobuttons are being selected. I tried to apply loop to your sample, but couldnt get it to work. I will like you to apply loop i.e For 1 to 4, so we can have three group together in four ways to know if your logic will retain one in each group. Thanks
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
It is easy enough to roll your own radio button action and put all of them into a BBCodeView.

B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private BBCodeView1 As BBCodeView
    Private textEngine1 As BCTextEngine
    Private allOptions As List
    Private busy As Boolean
End Sub

Public Sub Initialize
    allOptions.Initialize
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Dim targetPanel As B4XView = xui.CreatePanel("")     'In case there is other stuff on the page
    Root.AddView(targetPanel, 0, 0, Root.Width, Root.Height)
    textEngine1.Initialize(targetPanel)
    targetPanel.LoadLayout("MainPage")
    BBCodeView1.TextEngine = textEngine1
  
    'Three groups of four radio buttons
    Dim content As StringBuilder: content.Initialize
    Dim texts(4) As String = Array As String("Option 1", $"Line 1${CRLF}Line 2${CRLF}Line 3${CRLF}Line 4${CRLF}Line 5"$, "Option 3", "Option 4")
    For i = 0 To 2
        For j = 0 To 3        'j is button #
            Dim rb As RadioButton
            rb.initialize("RadioBtns")
            BBCodeView1.Views.Put("rb_" & i & "_" & j, rb)
            rb.Tag = Array As Int(i, j)
            content.Append($"[View=rb_${i}_${j} Vertical=3/]"$).Append(CRLF).Append($"[Indent=1]${texts(j)}[Indent=0]"$).Append(CRLF)
            allOptions.Add(rb)
        Next
    Next
    BBCodeView1.Text = content.toString
End Sub

Private Sub RadioBtns_SelectedChange(Selected As Boolean)
    If busy Then Return
    Dim rbx As RadioButton = Sender
    Dim which() As Int = rbx.tag
    If rbx.As(B4XView).Checked Then
        busy = True
        For Each rb As B4XView In allOptions
            Dim wh() As Int = rb.Tag
            If wh(0) = which(0) And wh(1)<>which(1) Then rb.Checked = False
        Next
        busy = False
    End If
End Sub
View attachment 140960
I tried this your solution, it worked well on PC with B4J, but it doesn't display radiobutton in android phones. I tried it on two android phones, radiobutton didnt show, but all other texts showed. Below is what it displayed on phone and PC:
Screenshot_20230405-192418.png
pc.jpg


I dont know what cause radiobutton not showing up on phones. I tested it on two different phones. Will this solution also work with other b4xradiobutton or AS_Radiobutton? What of this your solution possibility of working in B4I too, i dont have means of testing that now? Thanks
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
In B4A..
1. the code generated button doesn't have any dimensions.
2. the size values need to be in dips
3. the event name is different

In B4i
1. There is no RadioButton. You could use B4XRadioButton, but that can't be easily created in code.
I suggest the following... Make a pseudo RadioButton from a Label with two FontAwesome Icons as text
When clicked, switch the two icons.

The code below works for both B4J and B4A, and I don't see why it wouldn't work in B4i (not tested)

B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Dim targetPanel As B4XView = xui.CreatePanel("")     'In case there is other stuff on the page
    Root.AddView(targetPanel, 0, 0, Root.Width, Root.Height) 
    textEngine1.Initialize(targetPanel)
    targetPanel.LoadLayout("MainPage")
    BBCodeView1.TextEngine = textEngine1
    Dim voffset As Int = 6dip
    Dim w As Int = 25dip
    
    Dim content As StringBuilder: content.Initialize
    Dim texts(4) As String = Array As String("Option 1", $"Line 1${CRLF}Line 2${CRLF}Line 3${CRLF}Line 4${CRLF}Line 5"$, "Option 3", "Option 4")
    For i = 0 To 2
        For j = 0 To 3        'j is button #
            Dim rb As Label
            rb.initialize("PseudoBtn")
            Dim rbx As B4XView = rb
            rbx.SetLayoutAnimated(0, 0, 0, w, w)
            rbx.Font = xui.CreateFontAwesome(18)
            rbx.Text = Chr(0xF10C)
            rbx.Tag = i
            BBCodeView1.Views.Put("rb_" & i & "_" & j, rbx)
            content.Append($"[View=rb_${i}_${j} Vertical=${voffset}/]"$).Append($"[Indent=1]${texts(j)}[Indent=0]"$).Append(CRLF)
            allOptions.Add(rbx)
        Next
    Next
    BBCodeView1.Text = content.toString
End Sub

#If B4J
Private Sub PseudoBtn_MouseClicked(Ev As MouseEvent)
    Dim lbl As B4XView = Sender
    btnClick(lbl)
End Sub
#Else
Private Sub PseudoBtn_Click
    Dim lbl As B4XView = Sender
    btnClick(lbl)
End Sub
#Else If B4i
#End If

Private Sub btnClick(lbl As B4XView)
    Dim group As Int = lbl.tag
    If lbl.Text = Chr(0xF10C) Then
        For Each rb As B4XView In allOptions
            Dim grp As Int = rb.Tag
            If grp = group Then rb.Text = Chr(0xF10C)
        Next
        lbl.Text = Chr(0xF192)
    Else
        lbl.Text = Chr(0xF10C)
    End If
End Sub
 

Attachments

  • PseudoRadio.zip
    43.5 KB · Views: 49
  • screenShot.png
    screenShot.png
    23.5 KB · Views: 54
Upvote 0

teddybear

Well-Known Member
Licensed User
Thank you once again for this. I need this code to be in a loop before i can know if it works or not because only one must be selected in group of three. I copied important segment of code to B4xpages and put it on a loop after modifying it like this:

B4X:
For i = 1 To 4  'number of three groups four times
       
        pnl  = xui.CreatePanel("")
        pnl.SetLayoutAnimated(0, 0, 0, Root.Width, 200dip)
   
        pnl.LoadLayout("RadioButtons")
       
        For k = 0 To  pnl.NumberOfViews -1
            pnl.GetView(k).Tag = "Pnl" & i  ' if i remove & i, i will pnl logged in all 4 x 3 loop          '
       Next
     
        rb11  = pnl.GetView(0)
        rb21  = pnl.GetView(1)
        rb31 = pnl.GetView(2)
        Log(rb11.Tag)
        Log(rb21.Tag)
        Log(rb31.Tag)
next

As log, i got:
Pnl1
Pnl1
Pnl1
Pnl2
Pnl2
Pnl2
Pnl3
Pnl3
Pnl3
Pnl4
Pnl4
Pnl4

NOTE: I applied this loop to B4xradiobutton instead, all 4 x 3 radiobuttons are being selected. I tried to apply loop to your sample, but couldnt get it to work. I will like you to apply loop i.e For 1 to 4, so we can have three group together in four ways to know if your logic will retain one in each group. Thanks
Could you post a small project?
 
Upvote 0

omo

Active Member
Licensed User
Longtime User
In B4A..
1. the code generated button doesn't have any dimensions.
2. the size values need to be in dips
3. the event name is different

In B4i
1. There is no RadioButton. You could use B4XRadioButton, but that can't be easily created in code.
I suggest the following... Make a pseudo RadioButton from a Label with two FontAwesome Icons as text
When clicked, switch the two icons.

The code below works for both B4J and B4A, and I don't see why it wouldn't work in B4i (not tested)

B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Dim targetPanel As B4XView = xui.CreatePanel("")     'In case there is other stuff on the page
    Root.AddView(targetPanel, 0, 0, Root.Width, Root.Height)
    textEngine1.Initialize(targetPanel)
    targetPanel.LoadLayout("MainPage")
    BBCodeView1.TextEngine = textEngine1
    Dim voffset As Int = 6dip
    Dim w As Int = 25dip
   
    Dim content As StringBuilder: content.Initialize
    Dim texts(4) As String = Array As String("Option 1", $"Line 1${CRLF}Line 2${CRLF}Line 3${CRLF}Line 4${CRLF}Line 5"$, "Option 3", "Option 4")
    For i = 0 To 2
        For j = 0 To 3        'j is button #
            Dim rb As Label
            rb.initialize("PseudoBtn")
            Dim rbx As B4XView = rb
            rbx.SetLayoutAnimated(0, 0, 0, w, w)
            rbx.Font = xui.CreateFontAwesome(18)
            rbx.Text = Chr(0xF10C)
            rbx.Tag = i
            BBCodeView1.Views.Put("rb_" & i & "_" & j, rbx)
            content.Append($"[View=rb_${i}_${j} Vertical=${voffset}/]"$).Append($"[Indent=1]${texts(j)}[Indent=0]"$).Append(CRLF)
            allOptions.Add(rbx)
        Next
    Next
    BBCodeView1.Text = content.toString
End Sub

#If B4J
Private Sub PseudoBtn_MouseClicked(Ev As MouseEvent)
    Dim lbl As B4XView = Sender
    btnClick(lbl)
End Sub
#Else
Private Sub PseudoBtn_Click
    Dim lbl As B4XView = Sender
    btnClick(lbl)
End Sub
#Else If B4i
#End If

Private Sub btnClick(lbl As B4XView)
    Dim group As Int = lbl.tag
    If lbl.Text = Chr(0xF10C) Then
        For Each rb As B4XView In allOptions
            Dim grp As Int = rb.Tag
            If grp = group Then rb.Text = Chr(0xF10C)
        Next
        lbl.Text = Chr(0xF192)
    Else
        lbl.Text = Chr(0xF10C)
    End If
End Sub
This your new solution works flawlessly in B4J and B4A without problem and being labelic-solution derivative, i don't see reason why it wont work in B4I either. When i set rb.height and width to 25dip each, i was able to see radio button in the android version of the old solution. However, it couldnt retain one option in a group., but i prefer this your second solution since it works flawlessly as cross platform. I will see if i can add simple animation to it similar or better than that of radiobutton. Now, one more question, i was able to log grp, group and lbl.text, to know if i can get unique radiooption id to track individual option button, yes, grp was constant for each group while lbl.text is giving font awesome label, what is the unique id to program each button or should i just target side label and grp? Or should i setup another sender for integer? When i put message box and click, it fires for each button, but i need what will make me identify each button that fires so it can be easy for me to program that button
 
Upvote 0
Top