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.
问题:
回答1:
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..! :)
回答2:
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.
回答3:
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
回答4:
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, ...)
回答5:
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)
}
}
})