Я ищу метод программного изменения состояния виджета Android Switch с помощью switch.setChecked(true);
без запуска OnCheckedChangedlistener
.
Моей первой мыслью было заменить его на OnClickListener
, но так как он регистрирует только клики, и вы можете не только нажимать, но и двигать переключатель, то он не совсем подходит для этой цели, как если бы пользователь скользил Переключатель с выключенного на включенный, тогда переключатель фактически ничего не делает, поскольку пользователь не нажимает...
Если у кого-то есть решение или умный обходной путь для этого, это было бы здорово
Android - программно изменить состояние переключателя без запуска слушателя OnCheckChanged
Ответы (9)
Ну, прямо перед тем, как делать что-то в коде с помощью переключателя, вы можете просто отменить регистрацию прослушивателя, затем сделать все, что вам нужно, и снова зарегистрировать прослушиватель.
Установите прослушиватель на null перед вызовом функции setCheck() и включите его после этого, например:
switch.setOnCheckedChangeListener (null);
switch.setChecked(true);
switch.setOnCheckedChangeListener (this);
Справка: изменение значения флажка без срабатывания onCheckChanged
Каждая CompoundButton (кнопка с двумя состояниями — вкл./выкл.) нажата состояние, которое истинно только когда пользователь нажимает на представление.
Просто добавьте проверку в свой слушатель перед запуском фактической логики:
if(compoundButton.isPressed()) {
// continue with your listener
}
Таким образом, программное изменение проверенного значения не приведет к запуску нежелательного кода.
Из ответа @krisDrOid.
isPressed
часто будет ложным для взаимодействия с переключателем, а не касанием.
- person Roman Kotenko; 11.02.2021
У меня есть одно решение, и оно отлично работает на моем конце. Я добавил 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 вызывается только тогда, когда изменение проверки происходит в результате вмешательства человека путем перетаскивания, щелчка, прикосновения.
Также не забудьте добавить свой действительный строковый тег (не null), когда вы пытаетесь изменить статус проверки переключателя. подобно :
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.setChecked(true); // first set value (from pref or server or anywhere) and than switch.setOnCheckedChangeListener (this);
добавить слушателя.
Если ничего не сработало, это сложное решение.
Создайте текстовое представление поверх переключателя и добавьте clickListener в текстовое представление.
<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" />
Добавьте возвышение в текстовое представление.
Разработка ответа Махмуда
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);
}
`