How to use data binding for Switch onCheckedChageListener event?

Using lambda expression and a Switch:

public void onCheckedChanged(boolean checked) {
     // implementation      
}

XML file:

<android.support.v7.widget.SwitchCompat
    android:onCheckedChanged="@{(switch, checked) -> item.onCheckedChanged(checked)}"
    ...
/>

Where item is the class that implements onCheckedChange method and is imported to the XML file like this:

<data>
    <variable
        name="item"
        type="yourClass"/>
</data>

Different Ways

(1) Set by method expression

In layout

<variable
    name="activity"
    type="com.innovanathinklabs.sample.activities.CalendarActivity"/>

<Switch
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="@={model.checked}"
    android:onCheckedChanged="@{activity::onGenderChanged}"
    />

In Activity

class HomeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = DataBindingUtil.setContentView<ActivityCalendarBinding>(this, R.layout.activity_calendar)
        binding.activity = this
        binding.model = Model()
    }

    fun onGenderChanged(buttonView: CompoundButton, isChecked: Boolean) {
        println("buttonView = [$buttonView], isChecked = [$isChecked]")
    }
}

(2) Set by lambda expression and method call

<variable
    name="model"
    type="com.innovanathinklabs.sample.data.Model"/>

<variable
    name="activity"
    type="com.innovanathinklabs.sample.activities.HomeActivity"/>

<Switch
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="@={model.checked}"
    android:onCheckedChanged="@{(button, bool)-> activity.saveGender(bool)}"
    />

In Activity

class HomeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = DataBindingUtil.setContentView<ActivityCalendarBinding>(this, R.layout.activity_calendar)
        binding.activity = this
        binding.model = Model()
    }

    fun saveGender(isChecked: Boolean) {
        println("isChecked = [$isChecked]")
    }
}

(3) Pass OnCheckedChangeListener anonymous class to layout

<variable
    name="onGenderChange"
    type="android.widget.CompoundButton.OnCheckedChangeListener"/>

<Switch
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="@={model.checked}"
    android:onCheckedChanged="@{onGenderChange}"
    />

In Activity

class HomeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = DataBindingUtil.setContentView<ActivityCalendarBinding>(this, R.layout.activity_calendar)
        binding.model = Model()
        binding.setOnGenderChange { buttonView, isChecked ->
            println("buttonView = [$buttonView], isChecked = [$isChecked]")
        }
    }
}

(4) Pass OnCheckedChangeListener by reference

<variable
    name="onGenderChange2"
    type="android.widget.CompoundButton.OnCheckedChangeListener"/>

<Switch
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="@={model.checked}"
    android:onCheckedChanged="@{onGenderChange2}"
    />

Activity

class HomeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = DataBindingUtil.setContentView<ActivityCalendarBinding>(this, R.layout.activity_calendar)
        binding.model = Model()
        binding.onGenderChange2 = onGenderChange
    }

    private val onGenderChange: CompoundButton.OnCheckedChangeListener = CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
        println("buttonView = [$buttonView], isChecked = [$isChecked]")
    }
}

Now below will NOT work

Now if you set CheckChangeListener in code that will not work. because you can't set two callback on one component. One callback is already set by binding, so your callback in code will not work.

binding.mySwitch.setOnCheckedChangeListener { buttonView, isChecked ->
    println("buttonView = [$buttonView], isChecked = [$isChecked]")
}

Check CompoundButtonBindingAdapter class to see how Switch Binding works.