I use a CompoundButton
in my app. I call a method named newsLetterUpdate()
in the onCheckedChange()
callback of CompoundButton.OnCheckedChangeListener
. I change the checked state of this CompoundButton
programmatically, but the onCheckedChange()
callback gets invoked. I want the onCheckedChange()
to be triggered only if I switch the checked state on the View
.
Please suggest me a solution to change the state of compound button without the onCheckedChange()
callback to be invoked.
-
take one flag and set false when you change state compound button programmatically and check this flag value in onCheckedChanged() base do your code. – Haresh Chhelana Dec 05 '14 at 06:43
5 Answers
So as per your requirement I believe that you need to execute the code inside onCheckedChange()
call back only if the user initiates the action. Right?
Then why are you using onCheckedChange()
, you can use onClickListener()
instead to achieve your goal.
Currently you have possibly written your code inside:
compundbutton.setOnCheckedChangeListener(your_current_listener);
Move that code from there to :
compundbutton.setOnClickListener(your_new_listener);
Then onCheckedChange ()
listeners will not get invoked on setting checked state programiccally.
compundbutton.setChecked(checked);
Hope it may help you..! :)

- 1,647
- 2
- 18
- 29
-
I felt, unregister and register listener, this method is more efficient. Thanks – PK 7 Dec 31 '14 at 07:09
I have the similar issue. I had RadioGroup and when the user was opening the application I was setting the initial state and it was going in OnCheckedChangeListener and in my case was updating data in database which was very bad. I have solved it that in the OnCheckedChangedListener i was taking the button and setting in that method a OnClickListener:
viberPermissionView.getAppPermissions().setOnCheckedChangeListener(
new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup,
int checkedRadioButtonId) {
final RadioButton checkedButton =
viberPermissionView.findViewById(checkedRadioButtonId);
checkedButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startService(checkedButton,
App.VIBER);
}
});
}
});
With that when onCreate was called it was going in OnCheckedChangedListener but it wasn't going in OnClickListener. Only when the user will press the button it will go in OnClick and will execute in my case the startService. Hope this will help.

- 794
- 9
- 24
Method 1 : if you want on checkChangeListener
should only be called while use interacts with the view then implemenet onClickListener
put newsLetterUpdate
method in that class
Mehtod 2 : unregister the listener before you programmaticaly change the checkbox and register again when you are done
Method 3 : use a boolean flag... set it when you change checkbox programmactically and set if false to when u are done... guard the code with that flag which you want to execute with user interaction only

- 1,364
- 9
- 12
-
It should work the newsLetterUpdate() method in checkChangeListener too. Then?? – PK 7 Dec 05 '14 at 07:44
-
unregister the listener before you programmaticaly change the checkbox and register again when you are done .. for use a boolean flag... set it when you change checkbox programmactically and set if false to when u are done... guard the code with that flag which you dont want to execute with user interaction only – Munawwar Hussain Shelia Dec 05 '14 at 07:51
Method 4: Use a custom view
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Switch;
public class CustomSwitch extends Switch {
private OnCheckedChangeListener mListener;
public CustomSwitch(Context context) {
super(context);
}
public CustomSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomSwitch(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomSwitch(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
// Do not call supper method
mListener = listener;
}
@Override
public void setChecked(boolean checked) {
super.setChecked(checked);
if (mListener != null) {
mListener.onCheckedChanged(this, checked);
}
}
public void setCheckedProgrammatically(boolean checked) {
// You can call super method, it doesn't have a listener... he he :)
super.setChecked(checked);
}
}
Sample XML usage
<com.your.package.CustomSwitch
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Now the idea is to call the method setCheckedProgrammatically in code. setChecked gets called by Android when users changes the state of the compund button
Note that I'm using a switch, which extends the compund button, you can use basically the same code on any other (checkbox, ...)

- 15,488
- 2
- 54
- 59
You can check if onCheckedChange event is from user pressing the button, if you check isPressing value like this:
switch.setOnCheckedChangeListener(object : CompoundButton.OnCheckedChangeListener {
override fun onCheckedChanged(switch: CompoundButton?, checked: Boolean) {
if (switch == null) {
return
}
if (switch.isPressed) {
viewModel.onCheckedChanged(checked)
}
}
})

- 667
- 4
- 5