Aprenda a usar o SwitchCompact (On/Off) no Android (Kotlin)

SwitchCompact

O elemento switch é bem conhecido e usado mundialmente como o famoso toggle de ON/OFF.

SwitchCompact também é um elemento de interface do usuário de dois estados usado para alternar entre ON e OFF como um botão.

Ao tocar no botão, podemos arrastá-lo para frente e para trás para ativá-lo ou desativá-lo.

Para criar este elemento é só usar o <SwitchCompact>:

<androidx.appcompat.widget.SwitchCompat
android:id="@+id/switch_on_off"
android:text="Meu Switch"
android:checked="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

Podemos ter um texto atribuído ao nosso switch (android:text), como também reconhecer se ele já sem selecionado ou não (android:checked).

Validando o Switch via Código

Podemos validar o nosso switch via código por meio do atributo isChecked:

val switch = findViewById<View>(R.id.switch_on_off) as SwitchCompat//Seleciona a view SeekBar

switch.isChecked = false//Usado para trocar o valor do Switch via código

Log.d("Switch", "${switch.isChecked}")//Usado para verificar se o Switch está ativo ou não (retorna true ou false)

Eventos no Switch

Também podemos trabalhar com eventos no Switch, para isso, você precisa implementar na sua Activity ou Fragment a interface OnCheckedChangeListener:

class MainActivity : AppCompatActivity(), CompoundButton.OnCheckedChangeListener {
...
}

Em seguida precisamos dizer que a nossa Activity será responsável por conter os métodos do Switch:

val switch = findViewById<View>(R.id.switch_on_off) as SwitchCompat//Seleciona a view SeekBar

switch.setOnCheckedChangeListener(this)//usado para dizer a Activity que os métodos desse Switch existem dentro dessa Activity

Por fim, basta implementar o método obrigatório da interface:

override fun onCheckedChanged(button: CompoundButton, isChecked: Boolean) {
TODO("Not yet implemented")
}

onCheckedChanged: Método usado sempre quando o usuário trocar o valor do Switch.

Ele implementa dois métodos, o Button que chamou o switch, e o isChecked que retorna se o switch está ativo ou não.

Criando um Switch customizado

Atualmente não existe uma maneira fácil de criar um switch customizado.

E quando digo isso, estou me referindo na criação de um switch que por meio de atributos conseguimos mudar sua cor, e adicionar ícones dentro do círculo.

Infelizmente isso não é possível, e nesses casos, precisamos criar o layout desse switch manualmente usando elementos como <Stroke><Layer><Item> e afins.

O repositório que contém o switch customizado é o Switch-Customizado.

O Switch que iremos criar será igual a este da imagem abaixo:

Adicionando novas cores no colors.xml

Como um primeiro passo, devemos adicionar novas cores no arquivo colors.xml existente dentro da pasta res > values:

<resources>
...
<color name="gray">#aaa</color>
<color name="darkGray">#ff424242</color>
<color name="lavender">#E6E6FA</color>
</resources>

O esquema de cores que foram adicionados ao arquivo são respectivamente: graydarkGray e lavender.

Alterando o tema da aplicação (IMPORTANTE)

Se você está usando o Android Studio Flamingo na versão 2022.2.1 Patch 2.

Talvez o seu arquivo de themes.xml que existe na pasta res > values > themes, esteja configurado para executar o tema do Material3:

parent="Theme.Material3.DayNight.NoActionBar"

É importante ressaltar que as configurações do Switch personalizado, não funcionam quando estamos executando o tema do Material3, pois este tema não permite personalizações no SwitchCompact.

Para mais explicações acesse o vídeo neste link.

Nesse caso, você deve alterar o tema da sua aplicação para AppCompact da seguinte forma:

parent="Theme.AppCompat.DayNight.NoActionBar"

Feito isso, já podemos prosseguir com o desenvolvimento do Layout.

Criando os arquivos de Layout

Para criar aquele Switch que vimos na ilustração acima, precisamos criar dentro da pasta res > drawable, 4 arquivos do tipo XML:

track.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true">
<shape
android:shape="rectangle">
<solid
android:color="@color/darkGray" />
<size
android:height="8dp" />
<corners
android:radius="100dp" />
</shape>
</item>
<item android:state_checked="false">
<shape
android:shape="rectangle">
<solid
android:color="@color/lavender" />
<size
android:height="8dp" />
<corners
android:radius="100dp" />
</shape>
</item>
</selector>

thumbtrue.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="oval">
<solid
android:color="@color/white" />
<size
android:height="8dp"
android:width="8dp" />
<stroke
android:width="1dp"
android:color="@color/darkGray" />
</shape>
</item>
<item
android:drawable="@drawable/baseline_nightlight_round_24"
android:top="8dp"
android:bottom="8dp"
android:right="8dp"
android:left="8dp" />
</layer-list>

thumbfalse.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="oval">
<solid
android:color="@color/white" />
<size
android:height="8dp"
android:width="8dp" />
<stroke
android:width="1dp"
android:color="@color/lavender" />
</shape>
</item>
<item
android:drawable="@drawable/baseline_wb_sunny_24"
android:top="8dp"
android:bottom="8dp"
android:right="8dp"
android:left="8dp" />
</layer-list>

thumb.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="true"
android:drawable="@drawable/thumbtrue" />
<item
android:state_checked="false"
android:drawable="@drawable/thumbfalse" />
</selector>

Cada um desses arquivos é responsável por criar manualmente um estilo de layout diferente para o switch quando ele se encontra ativado ou desativado.

Importando os vetores (ícones)

Se você perceber, existem dois vetores (ícones) que representam a imagem de um sol e outro de uma lua, vamos cria-los dentro da pasta res > drawable:

baseline_nightlight_round_24.xml:

<vector android:height="24dp" android:tint="#424242"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12.01,12c0,-3.57 2.2,-6.62 5.31,-7.87 0.89,-0.36 0.75,-1.69 -0.19,-1.9 -1.1,-0.24 -2.27,-0.3 -3.48,-0.14 -4.51,0.6 -8.12,4.31 -8.59,8.83C4.44,16.93 9.13,22 15.01,22c0.73,0 1.43,-0.08 2.12,-0.23 0.95,-0.21 1.1,-1.53 0.2,-1.9 -3.22,-1.29 -5.33,-4.41 -5.32,-7.87z"/>
</vector>

baseline_wb_sunny_24.xml:

<vector android:height="24dp" android:tint="#8692F7"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M6.76,4.84l-1.8,-1.79 -1.41,1.41 1.79,1.79 1.42,-1.41zM4,10.5L1,10.5v2h3v-2zM13,0.55h-2L11,3.5h2L13,0.55zM20.45,4.46l-1.41,-1.41 -1.79,1.79 1.41,1.41 1.79,-1.79zM17.24,18.16l1.79,1.8 1.41,-1.41 -1.8,-1.79 -1.4,1.4zM20,10.5v2h3v-2h-3zM12,5.5c-3.31,0 -6,2.69 -6,6s2.69,6 6,6 6,-2.69 6,-6 -2.69,-6 -6,-6zM11,22.45h2L13,19.5h-2v2.95zM3.55,18.54l1.41,1.41 1.79,-1.8 -1.41,-1.41 -1.79,1.8z"/>
</vector>

Criando o SwitchCompact

Por fim, precisamos criar o elemento SwitchCompact na nossa Activity, não se esquecendo de atribuir os atributos android:thumb e android:track para que o sistema possa reconhecer o layout personalizado:

<androidx.appcompat.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/switchMode"
android:thumb="@drawable/thumb"
android:track="@drawable/track"
/>

E pronto, temos o SwitchCompact personalizado com sucesso!

Conclusão

Neste conteúdo você aprendeu a criar um Switch no Android Studio.

Até o próximo conteúdo.