Bug? toggle button and recursive call

Laurent95

Active Member
Licensed User
Longtime User
Hello,

I don't know why but in one of my application i use 5 toggle buttons like radio buttons.
The choice for toggle buttons is needed and it's more beautiful for design.
But they stay to don't work like radio buttons as far as i know.

For manage this, i use the code below who take care of the two states, Checked or not. Because i don't want that all toggle buttons can be off, that's not logical. And i want to display a message when the user touch a second time the toggle button even if this color is already set.

B4X:
Sub toggleColor_CheckedChange(Checked As Boolean)
    'only here for play a sound when the user push twice on the checked toggle
    If Not(Checked) Then
        playSound.Initialize
        playSound.Load(File.DirAssets,"bad.mp3")
    End If
    Dim b As String, Send As View
    Send=Sender
    b=Send.Tag
    'I use the tag property and the same Event
    Log("B Tag is " & b & " checked is " & Checked & " thisColor is " & thisColor)
    Select Case b
        Case "0"    'Green
            If Checked AND thisColor <> 0 Then
                thisColor = 0
                togColorPink.Checked = False
                togColorBlue.Checked = False
                TogColorMagenta.Checked = False
                TogColorYellow.Checked = False
            Else If Not(Checked) AND thisColor = 0 Then
                togColorGreen.Checked=True
                togColorPink.Checked = False
                togColorBlue.Checked = False
                TogColorMagenta.Checked = False
                TogColorYellow.Checked = False
                playSound.Play
            End If
        Case "1"    'Pink
            If Checked  AND thisColor <> 1 Then
                thisColor = 1
                togColorGreen.Checked = False
                togColorBlue.Checked = False
                TogColorMagenta.Checked = False
                TogColorYellow.Checked = False
            Else If Not(Checked) AND thisColor = 1 Then
                togColorGreen.Checked = False
                togColorPink.Checked=True
                togColorBlue.Checked = False
                TogColorMagenta.Checked = False
                TogColorYellow.Checked = False
                playSound.Play
            End If
        Case "2"    'Blue
            If Checked  AND thisColor <> 2 Then
                thisColor = 2
                togColorGreen.Checked = False
                togColorPink.Checked = False
                TogColorMagenta.Checked = False
                TogColorYellow.Checked = False
            Else If Not(Checked) AND thisColor = 2 Then
                togColorGreen.Checked = False
                togColorPink.Checked = False
                togColorBlue.Checked=True
                TogColorMagenta.Checked = False
                TogColorYellow.Checked = False
                playSound.Play
            End If
        Case "3"    'Magenta
            If Checked  AND thisColor <> 3 Then
                thisColor = 3
                togColorGreen.Checked = False
                togColorPink.Checked = False
                togColorBlue.Checked = False
                TogColorYellow.Checked = False
            Else If Not(Checked) AND thisColor = 3 Then
                togColorGreen.Checked = False
                togColorPink.Checked = False
                togColorBlue.Checked = False
                TogColorMagenta.Checked=True
                TogColorYellow.Checked = False
                playSound.Play
            End If
        Case "4"    'Yellow
            If Checked  AND thisColor <> 4 Then
                thisColor = 4
                togColorGreen.Checked = False
                togColorPink.Checked = False
                togColorBlue.Checked = False
                TogColorMagenta.Checked = False
            Else If Not(Checked) AND thisColor = 4 Then
                togColorGreen.Checked = False
                togColorPink.Checked = False
                togColorBlue.Checked = False
                TogColorMagenta.Checked = False
                TogColorYellow.Checked=True
                playSound.Play
            End If
    End Select
    'Do something after color index is set
End Sub

I don't know why, but recursive call happen only one time, even if i set the 4 other toggle buttons unchecked in the same part of code ?
(The log allow to verify it)
Edit :
The recursive call happen only when i touch a toggle button who is not checked.
If it's checked there are no recursive call ?
That seems weird.

Erel maybe could take a look, and explain why one time only.

This happen with a Genymotion virtual device and i work with B4A v3.8
I haven't tested that with another configuration.

Regards, Laurent
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Doesn't seem like a bug to me. You are setting the checked state and causing the event to fire again and again.

You should avoid duplicating code. Here is a my implementation that works correctly:
B4X:
Sub Globals
   Private ToggleButtons As List
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("1")
   ToggleButtons.Initialize
   For Each v As View In Activity.GetAllViewsRecursive
     If v Is ToggleButton Then ToggleButtons.Add(v)
   Next
End Sub


Sub ToggleButtons_CheckedChange(Checked As Boolean)
   If Checked = False Then Return
   Dim selected As ToggleButton = Sender
   For Each tb As ToggleButton In ToggleButtons
     If tb = selected Then Continue
     tb.Checked = False
   Next
End Sub
Make sure that the EventName of all toggle buttons is ToggleButtons.
 

Laurent95

Active Member
Licensed User
Longtime User
Doesn't seem like a bug to me. You are setting the checked state and causing the event to fire again and again.

Make sure that the EventName of all toggle buttons is ToggleButtons.

Hello,
I know that I call the Event recursively, that's not related with my question, it seems you have read too fast.
My question is : why only one recursive call, even if i set "4" toggle buttons unchecked when i put one checked ?
Logically it must be 4 recursive calls, not 1.

In the Edit i was a bit tired because it's understandable, if all is good i don't set any other toggle button in an another state than which one is it at this time.
Then i don't change anything just i show a message to the user.

EDIT :
Grrrrrrrrr, after a good shower i realize that i give a response myself to my question with this reply !
One recursive callback because only one toggle button checked at anytime.
Like my grand mother say, tomorrow it's another day ............

Thanks for your code Erel, but it don't respond to my case, i have two series of 5 toggle buttons that i use like radio buttons in my application.
All toggle buttons can't have the same event.
Note : As mine your code don't avoid the recursive call, just it reject at first line of the Sub in "unchecked" case.

Best regards.
 
Last edited:

Laurent95

Active Member
Licensed User
Longtime User
It should be simple to use similar code with two groups. The point is that you should avoid duplicating code.

Yes maybe, but it's your point of view.
Mine is that it's more maintainable with one "Sub Event" for each group, this application is in perpetual update.
I have the bad tendency to consider that 30.000 users, maybe more now, can ask some evolution :)
 

LucaMs

Expert
Licensed User
Longtime User
I don't know why, but recursive call happen only one time, even if i set the 4 other toggle buttons unchecked in the same part of code ?
(The log allow to verify it)


It fires only one time because you set thisColor, which is then used as a criterion for the "IF" statements.

Avoid to duplicate code is absolutly right: few lines of code = few errors, easier maintenance.
 
Last edited:
Top