Switch En Android

El Switch en Android es un widget con un control deslizante que te permite elegir entre dos posibles estados. Cambia entre sus valores arrastrando la palanca redondeada sobre el carril en el que se encuentra o simplemente haz click en el botón.

Visual de un Switch en Android

Su objetivo es informarle al usuario sobre la persistencia de un estado de activación/desactivación en un contexto dado. Algunos ejemplos de sus usos lo vemos en las preferencias de usuario de las apps, la persistencia de la activación de una alarma, habilitación de campos adicionales en un formulario y muchos otros.

La Clase Switch

En el SDK este widget está representado por la clase Switch, la cual funciona desde la API 14 hacia arriba. También existe la clase SwitchCompat para compatibilidades hasta la API 7 y SwitchMaterial para crear switches con el tema de material design.

La clase Switch en Android

Claro está, que al ser hijas de CompoundButton, tendrán acceso a los tres métodos de la interfaz Checkable: isChecked() para determinar si está activo, setChecked() para cambiar el estado y toggle() para invertir el valor del estado actual.

Agregar Switch En Android Studio

Para añadir elementos de la clase Switch en el editor de layouts, dirígete a la paleta y haz click en la sección de Buttons. Luego arrastra la opción Switch a tu layout.

Switch en el Layout Editor de Android Studio

Recuerda que una forma más fácil de encontrarlo es usar la lupa para buscar al tipear el nombre del view.

Al agregarlo a un layout podrás ver una etiqueta <Switch> similar a la siguiente:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">    

    <Switch
        android:id="@+id/switch1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Switch"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Sin embargo, Android Studio te aconsejará que es mejor usar SwitchCompat o SwitchMaterial.

Warning al usar Switch en Android Studio

Por lo que usamos cualquiera de esos dos elementos en nuestra etiqueta. Por ejemplo:

<com.google.android.material.switchmaterial.SwitchMaterial
    android:id="@+id/switch1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Switch"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

Crear Switch Programaticamente

Cuando desees crear una instancia de la clase Switch usa cualquier de sus constructores públicos disponibles.

  • Switch(Context context)
  • Switch(Context context, AttributeSet attrs)
  • Switch(Context context, AttributeSet attrs, int defStyleAttr)
  • Switch(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)

Por ejemplo, supongamos que nos encontramos en una actividad y deseamos crear un SwitchMaterial dinámicamente. Si su padre fuera un ConstraintLayout, entonces el código se vería así:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val root = findViewById<View>(R.id.layout) as ConstraintLayout
        val switch = SwitchMaterial(this).apply {
            text = "Switch agregado en tiempo de ejecución"
            isChecked = true
        }
        root.addView(switch)
    }
}

Escuchar Cambios De Estado

Usa el método setOnCheckedChangeListener() para suscribir instancias del tipo OnCheckedChangedListener con el fin de procesar los eventos de cambio de estado en el Switch.

val switch = findViewById<SwitchMaterial>(R.id.switch1)
switch.setOnCheckedChangeListener { buttonView, isChecked ->
    if (isChecked) {
        // Acciones al estar activo
    } else {
        // Acciones al estar inactivo
    }
}

Como ves, la expresión de objeto puede convertirse en una función lambda, cuyos parámetros son el CompoundButton alterado (buttonView) y su estado de activación (isChecked).

Cambiar Tema De Un Switch

A la hora de realizar modificaciones a las propiedades visuales de un Switch es necesario crear un recurso de tipo <style> con la personalización de los atributos asociados.

Por ejemplo, si deseáramos aplicar un color diferente que reemplace a los del tema principal de la aplicación, entonces creamos un estilo cuyo padre sea Widget.MaterialComponents.CompoundButton.Switch.

Luego aplicamos los colores elegidos en los atributos colorOnSurface y colorSecondary.

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.SwitchEnAndroid" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- ... -->
        <item name="switchStyle">@style/Widget.App.Switch</item>
    </style>

    <style name="Widget.App.Switch" parent="Widget.MaterialComponents.CompoundButton.Switch">
        <item name="materialThemeOverlay">@style/ThemeOverlay.App.Switch</item>
    </style>

    <!-- Tema personalizado para Switch-->
    <style name="ThemeOverlay.App.Switch" parent="">
        <item name="colorOnSurface">@color/lime_900</item>
        <item name="colorSecondary">@color/lime_100</item>
    </style>
</resources>

Ejemplo De Switch En Android

En los siguientes pasos verás cómo crear una app que cambie el formato de un texto a partir de dos controles switch. El primero activa o desactiva el uso de formato itálico y el segundo activa/desactiva el resaltado del texto.

Resultado ejemplo de Switch en Android

Si deseas puedes obtener el código desde el siguiente enlace:

Veamos la construcción de esta sencilla app.

Paso 1. Crea un nuevo proyecto en Android Studio llamado «Switch En Android». Selecciona como lenguaje principal a Kotlin, usa la plantilla Empty Activity y nombra a la actividad principal MainActivity.

Paso 2. Abre el layout main_activity.xml y modifícalo con la agregación de dos MaterialSwitch y un TextView.

Usa el siguiente conjunto de atributos:

  • Texto (user_text): El texto del usuario posiciónalo en la parte superior del padre
  • Switch 1 (switch_italic_format): Conecta su borde superior sobre el borde inferior del texto. Expándelo horizontalmente
  • Switch 2 (switch_highlighted): Conecta su borde superior con el borde inferior del switch 1. Expandelo horizontalmente

Al terminar tendrás una layout similar al siguiente:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/user_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/user_text"
        android:textAppearance="@style/TextAppearance.MaterialComponents.Headline4"
        android:textColor="@color/black"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.switchmaterial.SwitchMaterial
        android:id="@+id/switch_italic_format"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="@string/italic_format"
        android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/user_text" />

    <com.google.android.material.switchmaterial.SwitchMaterial
        android:id="@+id/switch_highlighted"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/highlighted"
        android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.507"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/switch_italic_format" />

</androidx.constraintlayout.widget.ConstraintLayout>

Y en la pestaña de Split verás la prevista así:

Diseño de Switch en Layout

Paso 3. Lo siguiente es agregar la lógica de los eventos sobre MainActivity.kt. Nuestro objetivo es manipular el estilo del texto a partir de escuchar las variaciones en ambos switches, por lo que requeriremos:

  1. Tomar las referencias de los dos MaterialSwitch y el TextView
  2. Asignar una escucha a switch 1 y aplicar el estilo itálico si está activo, o normal en caso contrario
  3. Asignar una escucha a switch 2 y cambiar el color del texto a R.color.green_500. si está activo, o negro en caso contrario

Teniendo en cuenta estas instrucciones el código XML en la actividad se vería así:

class MainActivity : AppCompatActivity() {
    private lateinit var text: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        text = findViewById(R.id.user_text)

        setupItalicSwitch()

        setupHighlightedSwitch()
    }

    private fun setupItalicSwitch() {
        val italicSwitch: SwitchMaterial = findViewById(R.id.switch_italic_format)

        italicSwitch.setOnCheckedChangeListener { _, isChecked ->
            val typeface = if (isChecked) Typeface.ITALIC else Typeface.NORMAL
            text.setTypeface(null, typeface)
        }
    }

    private fun setupHighlightedSwitch() {
        val colorSwitch: SwitchMaterial = findViewById(R.id.switch_highlighted)

        colorSwitch.setOnCheckedChangeListener { _, isChecked ->
            val colorRes = if (isChecked) R.color.green_500 else R.color.black
            text.setTextColor(getColorValue(colorRes))
        }
    }

    private fun getColorValue(@ColorRes colorRes: Int): Int {
        return ContextCompat.getColor(this, colorRes)
    }
}

Como ves, hemos creado dos método para procesar la preparación de ambos switches desde onCreate().

El primero, setupItalicSwitch(), obtiene la instancia de R.id.switch_italic_format y luego le asigna la escucha de eventos. Dependiendo del valor de isChecked, la variable typeface será asignada con ITALIC o NORMAL. Al final se aplica el estilo al texto del usuario con setTypeface().

El segundo, setupHighlightedSwitch(), ejecuta una operación similar, solo que esta vez el valor de isChecked determina el recurso de color por asignar. Luego se llama a setTextColor() sobre el texto de usuario.

Salida:

Al correr la aplicación y mover a las palancas de cada switch verás al texto variando entre las dimensiones diseñadas al principio.

Ejemplo de Switch En Android

Únete Al Discord De Develou

Si tienes problemas con el código de este tutorial, preguntas, recomendaciones o solo deseas discutir sobre desarrollo Android conmigo y otros desarrolladores, únete a la comunidad de Discord de Develou y siéntete libre de participar como gustes. ¡Te espero!