15

Is there any workaround helps me to programmatically change the state of Switch widget using switch.setChecked(true); without triggering OnCheckedChangedlistener()?

switch.setChecked(true); trigger OnCheckedChangedlistener() automatically but I need it triggered only when the user changes the state manually. So I need to stop
switch.setChecked(true); triggering OnCheckedChangedlistener()

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Safa
  • 473
  • 5
  • 22
  • you can use switch.setChecked(true/false) as you said – Geethakrishna Juluri Jan 16 '18 at 13:25
  • but it trigger `OnCheckedChangedlistener()` automatically which i need it triggered only when user change state manually – Safa Jan 16 '18 at 13:27
  • automatically triggering meaning? – Geethakrishna Juluri Jan 16 '18 at 13:29
  • 1
    When add this line `switch.setChecked(true/false)` to change state based on response from API and debug i found that, this code called @Override public void onCheckedChanged(SwitchButton view, boolean isChecked) { if (isChecked) { requestPermissions(); } } – Safa Jan 16 '18 at 13:31

4 Answers4

15

I worked around this problem by using setOnClickListener() instead of setOnCheckedChangeListener(), then I can use isChecked inside the click listener to know whether the Switch is checked or not, e.g.:

switchView.setOnClickListener {
    val isChecked = switchView.isChecked

    // Do something with the check status
}
Franco
  • 2,711
  • 2
  • 20
  • 27
13

Instead of using onClickListener to handle switch events you should use

 mySwitch.setOnCheckedChangeListener { compoundButton, isChecked ->
    if (compoundButton?.isPressed == true) 
        viewModel.onMySwitchChanged(isChecked)
}

the check if (compoundButton?.isPressed == true) prevent running viewModel.onMySwitchChanged when you set the switch state like mySwitch.isChecked = true or mySwitch.isSelected = true

NewbornDroid
  • 247
  • 1
  • 3
  • 12
6

You can remove that listener first and set it again after.

switch.setOnCheckChangedListener(null);
switch.setChecked(true);
switch.setOnCheckChangedListener(mOnCheckChangedListener);
egoldx
  • 1,490
  • 1
  • 9
  • 14
  • I tried this solution but after set listener again it behave like user clicked switch and call `OnCheckChangedListener()` – Safa Jan 16 '18 at 13:37
  • well, you could try some workaround, `switch.post(() -> switch.setOnCheckChangedListener(mOnCheckChangedListener))` – egoldx Jan 16 '18 at 13:40
  • Same behavior, it's really so weird :( – Safa Jan 16 '18 at 14:06
2

2 ways:

  1. Whenever you change programmatically, maintain a boolean variable and set it to true. In OnCheckedChangeListener(), check if has come from the user or programmatically.

  2. (Not recommended) Before you change programmatically, set yourSwtich.setOnCheckedChangeListener(null) to null. Then in next line again set your listener

  • 1- when i set the boolean variable in `OnCheckedChangeListener()` it will be always true even i changed it before `switch.setChecked(true/false)` as once it called `OnCheckedChangeListener()` it will be true 2- I tried this solution but after set listener again it behave like user clicked switch and call `OnCheckChangedListener()` – Safa Jan 16 '18 at 14:20
  • 1
    For(1) first answer, you have to set that boolean variable as false always in OnCheckedChangeListener() at the end. And before changing programmatically you have to set it to true. – Geethakrishna Juluri Jan 17 '18 at 05:41