我正在寻找一种在switch.setChecked(true);
不触发的情况下以编程方式更改 Android Switch 小部件状态的方法OnCheckedChangedlistener
。
我的第一个想法是把它换成一个,OnClickListener
但是因为这只会记录点击,你不仅可以点击,还可以滑动一个开关,那么它并不适合用户将开关从关闭滑到打开的目的由于用户没有点击,Switch实际上什么都不做……
如果有人对此有解决方案或聪明的解决方法,那就太棒了
10 回答
在调用setCheck()函数之前将监听器设置为null ,然后再启用它,例如:
switch.setOnCheckedChangeListener (null);
switch.setChecked(true);
switch.setOnCheckedChangeListener (this);
好吧,就在使用开关在代码中执行操作之前,您可以取消注册监听器,然后做任何您需要做的事情,然后再次注册监听器。
每个CompoundButton(两种状态按钮 - 开/关)都有一个按下状态,仅当用户按下视图时才为真。
只需在开始实际逻辑之前在您的侦听器中添加一个检查:
if(compoundButton.isPressed()) {
// continue with your listener
}
这样,以编程方式更改检查值不会触发不需要的代码。
来自@krisDrOid 的回答。
我有一个解决方案,它在我的最后工作正常。我在我的开关控件上添加了 setOnTouchListener 和 setOnCheckedChangeListener,并添加了以下代码来解决我的问题。
// set tag by default.
mMySwitch.setTag("TAG");
// Add OnCheckedChangeListener.
mMySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mMySwitch.getTag() != null) {
mMySwitch.setTag(null);
return;
}
// Do your stuff here.
}
});
// Add Touch listener.
mMySwitch.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mMySwitch.setTag(null);
return false;
}
});
这样,只有在通过拖动、单击、触摸等人工干预发生检查更改时,才会调用 setOnCheckedChangeListener。
当您尝试更改开关控制的检查状态时,也不要忘记添加您的有效字符串标签(非空)。像 :
mMySwitch.setTag("TAG");
mMySwitch.setChecked(true);
编写自定义 Switch 或 SwitchCompat 并覆盖 setOnCheckedListener。
public class SwitchCompat extends android.support.v7.widget.SwitchCompat {
private boolean mIgnoreCheckedChange = false;
public SwitchCompat(Context context) {
super(context);
}
public SwitchCompat(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SwitchCompat(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setOnCheckedChangeListener(final OnCheckedChangeListener listener) {
super.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mIgnoreCheckedChange) {
return;
}
listener.onCheckedChanged(buttonView, isChecked);
}
});
}
public void setChecked(boolean checked, boolean notify) {
mIgnoreCheckedChange = !notify;
setChecked(checked);
mIgnoreCheckedChange = false;
}
}
我能找到的最佳解决方案是;
const val SWITCH_COMPAT_IGNORE_TAG = "SWITCH_COMPAT_IGNORE_TAG"
fun SwitchCompat.isCheckedWithIgnoreTag(isChecked: Boolean) {
tag = SWITCH_COMPAT_IGNORE_TAG
this.isChecked = isChecked
tag = null
}
switchCompat.isCheckedWithIgnoreTag(true)
switchCompat.setOnCheckedChangeListener { buttonView, isChecked ->
if (buttonView.tag != SWITCH_COMPAT_IGNORE_TAG) {
//TODO
}
}
对于写<Switch/>
在 xml 上的默认开关,在 kotlin 中执行此操作以编程方式设置它:
mySwitch.isChecked = true
然后,如果您想在用户单击它时执行一些操作:
mySwitch.setOnCheckedChangeListener { compoundButton, isChecked ->
when (isChecked) {
true -> { /* do something here*/ }
false -> { /* do something here*/ }
}
}
详细说明马哈茂德的回答
CompoundButton.OnCheckedChangeListener switchListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
switchListener = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
//Implement on check change
}
};
switch.setOnCheckedChangeListener (switchListener);
//When you want to trigger the checked of switch do the following
switch.setOnCheckedChangeListener (null);
switch.setChecked(true);
switch.setOnCheckedChangeListener (switchListener);
}
`
使用这个
switch.setChecked(true); // first set value (from pref or server or anywhere) and than switch.setOnCheckedChangeListener (this);
添加监听器。
如果这里没有任何工作是一个棘手的解决方案。
在 switch 顶部创建一个 textview 并将 clickListener 添加到 textview。
<TextView
android:elevation="1dp"
android:id="@+id/switchLabel"
android:layout_width="0dp"
android:layout_height="0dp"
android:text=""
app:layout_constraintBottom_toBottomOf="@id/switch1"
app:layout_constraintStart_toStartOf="@+id/switch1"
app:layout_constraintTop_toTopOf="@id/switch1"
app:layout_constraintEnd_toEndOf="@id/switch1" />
向文本视图添加高度。