SwitchCompat
位于android.support.v7.widget下,比Switch 向下兼容性更好。
在使用过程中,需要在转换过程调用接口,成功则保持当前的选中状态,否则切换另一种状态。但是调用setChecked方法后,监听器OnCheckedChangeListener都会收到通知。
翻阅源码:
/**
* <p>Changes the checked state of this button.</p>
*
* @param checked true to check the button, false to uncheck it
*/
public void setChecked(boolean checked) {
if (mChecked != checked) {
mChecked = checked;
refreshDrawableState();
notifyViewAccessibilityStateChangedIfNeeded(
AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
// Avoid infinite recursions if setChecked() is called from a listener
if (mBroadcasting) {
return;
}
mBroadcasting = true;
if (mOnCheckedChangeListener != null) {
mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
}
if (mOnCheckedChangeWidgetListener != null) {
mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
}
mBroadcasting = false;
}
}
注意看上述代码,其中
if (mOnCheckedChangeListener != null) {
mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
}
if (mOnCheckedChangeWidgetListener != null) {
mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
}
才是上述问题的原因。
解决办法:
很简单,加个Tag标记一下就好了
if (toggle) {
toggle = !toggle;
return;
}
主动调用setChecked方法前讲toggle设为true即可,测试:小米6(miui 9.5 Android
8.0),完美通关。然后测试 vivo x21(OS 1.22.3 Android 8.1)两次之后失败开始,调式后发现toggle一直都是true,说明主动调用setChecked方法后OnCheckedChangeListener并没有收到通知,说明上述代码方法被改动了。
终极解决办法:
if (null != mSwitch) {
mSwitch.setOnCheckedChangeListener(null);
mSwitch.toggle();
mSwitch.setOnCheckedChangeListener(MainActivity.this);
}
手动调用前,先移除监听,调用完了再设置回去。