android
widget
Switch
event listener
on/off

android.widget.Switch - on/off event listener?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

For android.widget.Switch, the normal on/off listener is setOnCheckedChangeListener. A switch is just a two-state CompoundButton, so the event you care about is whether it became checked or unchecked. The main implementation detail is not how to attach the listener, but how to avoid confusing initialization-time state changes with real user actions.

The Standard Listener

A basic setup in Kotlin looks like this:

kotlin
1val mySwitch = findViewById<Switch>(R.id.mySwitch)
2
3mySwitch.setOnCheckedChangeListener { _, isChecked ->
4    if (isChecked) {
5        println("Switch is ON")
6    } else {
7        println("Switch is OFF")
8    }
9}

The second argument, isChecked, tells you the new state after the toggle.

The equivalent Java code is:

java
1Switch mySwitch = findViewById(R.id.mySwitch);
2
3mySwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
4    if (isChecked) {
5        System.out.println("Switch is ON");
6    } else {
7        System.out.println("Switch is OFF");
8    }
9});

Add the Switch in XML

A simple XML declaration might be:

xml
1<Switch
2    android:id="@+id/mySwitch"
3    android:layout_width="wrap_content"
4    android:layout_height="wrap_content"
5    android:text="Notifications" />

Then attach the listener after setContentView(...) in an Activity or after the view is created in a Fragment.

Save the State When It Matters

A switch is often tied to a preference or feature flag. In that case, update persistent state inside the listener.

kotlin
1mySwitch.setOnCheckedChangeListener { _, isChecked ->
2    val prefs = getSharedPreferences("settings", MODE_PRIVATE)
3    prefs.edit().putBoolean("notifications_enabled", isChecked).apply()
4}

This makes the UI reflect a setting rather than just printing a message.

Be Careful With Programmatic Changes

If you set the switch state in code, the listener can fire there too.

kotlin
mySwitch.isChecked = true

That means a listener may run during setup, state restoration, or other non-user actions. If that matters, guard the initialization phase.

kotlin
1var initializing = true
2
3mySwitch.setOnCheckedChangeListener { _, isChecked ->
4    if (initializing) return@setOnCheckedChangeListener
5    println("User changed switch to $isChecked")
6}
7
8mySwitch.isChecked = true
9initializing = false

This is useful when the listener should react only to user intent, not to state synchronization.

Distinguish State Change From Click

You can also attach a click listener, but it answers a different question.

  • 'setOnCheckedChangeListener tells you the switch state changed'
  • 'setOnClickListener tells you the view was clicked'

For most on/off logic, setOnCheckedChangeListener is the correct API because the real concern is the resulting checked state.

Use SwitchCompat in AppCompat Projects

In modern Android apps, SwitchCompat is often preferred over the platform Switch, especially when you want consistent styling on older Android versions.

The listener logic is the same because SwitchCompat is still a CompoundButton.

kotlin
1val mySwitch = findViewById<SwitchCompat>(R.id.mySwitch)
2mySwitch.setOnCheckedChangeListener { _, isChecked ->
3    println(isChecked)
4}

So if you are using AppCompat or Material components, the event-handling pattern does not really change.

Common Pitfalls

A common mistake is using a click listener when the actual requirement is to respond to state changes. The checked-change listener is more direct and less ambiguous.

Another issue is forgetting that programmatic calls such as isChecked = true can trigger the listener too. That can make setup code look like user interaction unless you guard against it.

Developers also sometimes update preferences or network state in the listener without restoring the switch from those sources first, which can lead to UI and saved-state drift.

Finally, if you are styling for broad Android support, do not assume the framework Switch is the best widget. SwitchCompat is often the safer default.

Summary

  • Use setOnCheckedChangeListener to handle on/off changes for a switch.
  • The isChecked argument tells you the new state directly.
  • Watch out for listener calls triggered by programmatic state changes during setup.
  • Use a checked-change listener for state logic, not a click listener.
  • In modern AppCompat projects, SwitchCompat is often the better widget choice.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions