Android Question checkbox change state programmatically

ilan

Expert
Licensed User
Longtime User
hi

the problem by changing the checkbox checked value to true/false in code is that it will raise its CheckedChange event.

i can use a global variable to check if i changed it or the user clicked on it but i think it is not the best way to do it.

what i have found is that the checkbox view also has a click event (not in b4a) so it would be great if we would have such thing.

Answer 2:

A very simple answer:

Use on OnClickListener instead of OnCheckedChangeListener

someCheckBox.setOnClickListener(newOnClickListener(){

@Overridepublicvoid onClick(View v){// you might keep a reference to the CheckBox to avoid this class castbooleanchecked=((CheckBox)v).isChecked();
setSomeBoolean(checked);}

});
Now you only pick up click events and don't have to worry about programmatic changes.

https://stackoverflow.com/questions...h-checkbox-value-is-changed-by-user-or-progra
 

mangojack

Expert
Licensed User
Longtime User
Just manually add it ..
B4X:
Sub chkBox_Click()      
    Dim chk As CheckBox = Sender
    Log($"${chk.Tag}  has been clicked"$)       
End Sub
 
Upvote 0

Kirk Grayson

Member
Licensed User
Hey MangoJack, could you please break your code down for me please. I have an issue with changing the checked state and it is calling the CheckedChange event.

Just manually add it ..
B4X:
Sub chkBox_Click()     
    Dim chk As CheckBox = Sender
    Log($"${chk.Tag}  has been clicked"$)      
End Sub

Thanks
 
Upvote 0

mangojack

Expert
Licensed User
Longtime User
I don't think I can break it down any further .. its only 2 lines.

Re-read the first post.
If you change the checked state by code it will raise the CheckedChange event
See @ilan comment about using global variable to flag non user change.
 
Upvote 0

Kirk Grayson

Member
Licensed User
I don't think I can break it down any further .. its only 2 lines.

Re-read the first post.

See @ilan comment about using global variable to flag non user change.

I do appreciate the speedy response. Thank you very much.
Maybe Im not asking the question properly, so let me try again;

I have Sub (VerifyState) that checks a text file and identifies the state when the activity is loaded. It then sets the checkbox state from the file.
The problem is I keep getting my msgbox '001Checked' because the sub that verifies when the checkbox is checked or not executes on the activity load.

B4X:
Sub VerifyState
If "checked" = File.ReadString(File.DirInternal, "Usr1Go.txt") Then
            chbUser1.Checked = True
        Else
            chbUser1.Checked = False
End If
End Sub       

Sub chbUser1_CheckedChange(Checked As Boolean)        
If chbUser1.Checked = True Then
    msgbox ("001Checked","")
    ' Store checked in the text file
else
    msgbox ("002 Not checked","")
    'store unchecked in the text file
end if
end sub

I will try @ilan suggestion. But I was just curious how your code works.
 
Upvote 0

mangojack

Expert
Licensed User
Longtime User
as @ilan suggested .. something like ..

B4X:
Private flagVerify as Boolean

Sub VerifyState
    flagVerify = True
    If "checked" = File.ReadString(File.DirInternal, "Usr1Go.txt") Then
      chbUser1.Checked = True
    Else
      chbUser1.Checked = False
    End If
End Sub   

Sub chbUser1_CheckedChange(Checked As Boolean)
    if flagVerify then
      flagVerify = false
      return
    end if

    'do something  ...
end sub

*re-doing Pc .. so not tested.

Regarding above snippet .. research the Sender object.
B4X:
Sender As Object
Returns the object that raised the event.
Only valid while inside the event sub.

Example:
Sub Button_Click
  Dim b As Button
  b = Sender
  b.Text = "I've been clicked"
End Sub
 
Upvote 0

Kirk Grayson

Member
Licensed User
Thanks MangoJack
This pretty much nails it. Its behaving close to as how I want it, I just think my if statements are not in the correct order.

B4X:
Private flagVerify as Boolean

Sub VerifyState
    flagVerify = True
    If "checked" = File.ReadString(File.DirInternal, "Usr1Go.txt") Then
            chbUser1.Checked = True
       Else
            chbUser1.Checked = False
    End If
End Sub    

Sub chbUser1_CheckedChange(Checked As Boolean)      
    If chbUser1.Checked = True Then
        msgbox ("001 Checked","")
        ' Store checked in the text file
    Else
        msgbox ("002 Not checked","")
        'store unchecked in the text file
    End If
End Sub

What I'm noticing is if I am in a unchecked state (002) during the Sub VerifyState, and I switch to a checked state during Sub chbUser1_CheckedChange, nothing happens (on the first click) because of the return exiting the sub. But doing it again does facilitate the switch.

Update: I added flagVerify = False after the chbUser1.Checked = False line and it works perfectly.
Thanks a bunch MangoJack.
 
Last edited:
Upvote 0

mangojack

Expert
Licensed User
Longtime User
What I'm noticing is if I am in a unchecked state (002) during the Sub VerifyState, and I switch to a checked state during Sub chbUser1_CheckedChange, nothing happens (on the first click) because of the return exiting the sub. But doing it again does facilitate the switch.

Update: I added flagVerify = False after the chbUser1.Checked = False line and it works perfectly.
Thanks a bunch MangoJack.

? I dont see how that works .. the purpose of Return in CheckedChanged was exit the Event if flag is True (checked state was changed programmatically)
Anyway .. If it works for you all is good ..

*EDIT .. I think I see your reasoning ..

Tip .. use Log() in debug rather than msgbox ..
B4X:
Sub chbUser1_CheckedChange(Checked As Boolean)     
     If Checked Then
        Log("checked")
        ' Store checked in the text file
    Else
        Log("unchecked")
        'store unchecked in the text file
    End If
End Sub
 
Last edited:
Upvote 0

ilan

Expert
Licensed User
Longtime User
maybe something like this?

B4X:
Sub Globals
    Private userchanged As Boolean
    Private checkbox1 As CheckBox
End Sub

Sub Activity_Create(FirstTime As Boolean)
    checkbox1.Initialize("checkbox1")
    checkbox1.Text = "Checkbox1"
    Activity.AddView(checkbox1,0,0,200,100)
    loadsettings
End Sub

Sub checkbox1_CheckedChange(Checked As Boolean)
    If userchanged Then Return 'exit if user changed
    File.WriteString(File.DirInternal,"check.txt",returnInt(Checked)) 'save new state to settings file
End Sub

Sub loadsettings
    userchanged = True 'set user change to true
    checkbox1.Checked = returnBol(File.ReadString(File.DirInternal,"check.txt")) 'update checkbox1 without performing Checkbox1 event
    userchanged = False 'set user change to false
End Sub

Sub returnInt(bol As Boolean) As Int
    Select bol
        Case True
            Return 1
        Case False
            Return 0   
    End Select
End Sub

Sub returnBol(int1 As Int) As Boolean
    Select int1
        Case 0
            Return False
        Case 1
            Return True   
    End Select
End Sub
 
Upvote 0
Top