Switch はよく設定などで使われるON/OFFのウィジェットの1つです
2024.1.1
Switch
Button、CompoundButton を継承しているのでタップをトリガーとして何らかの挙動をさせるという使い方になります
java.lang.Object | |||||
↳ | android.view.View | ||||
↳ | android.widget.TextView | ||||
↳ | android.widget.Button | ||||
↳ | android.widget.CompoundButton | ||||
↳ | android.widget.Switch |
似たようなウィジェットとしてSwitchCompatとSwithMaterialというのもあります
というのは、UseSwitchCompatOrMaterialXml のwarningが出てきます
- Switch
- Platformに依存してスイッチの表示が異なりますが、古いKitKat以前でのことであり Android OSシェア は数%以下です
- SwitchCompat
- MaterialDesignを継承
- androidx.appcompat.widget のSwith ウィジェット
- SwitchMaterial
- SwitchCompatを継承
- Material Components Library のライブラリから
SwitchもSwitchCompatも基本的なところはあまり変わらないのでSwitchCompatを使ったほうがいいというGoogleの推奨なんでしょうか
SwitchMaterialはSwitchCompatを継承していますが、SwitchとSwitchCompatには継承関係はありません、ただ同じCompoundButtonを継承しています
Switch トグルウィジェット
PaletのButtonグループにSwitchがあるので画面に配置します
Codeを見るとWarningが出ているので
tools:ignore=”UseSwitchCompatOrMaterialXml”
これでSwitchCompatやMaterialのリントを無視する設定を追加します
これはコードでもwarningが出てきます
1 2 3 4 5 6 7 8 9 10 11 |
<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" app:layout_constraintVertical_bias="0.3" tools:ignore="UseSwitchCompatOrMaterialXml" /> |
android:text=”xxx” でテキストを設定できるのですが、レイアウトに気を付けないとSwitchを並べるとアンバランスになってしまいます
これはテキストとSwithを合わせた横サイズが異なってしまうからなので
例えば、
android:layout_width=”200dp”
で統一しておけばalignmentが上手くいきます
タップやフリップでSwithの変更を受け取るには
setOnCheckedChangeListener
onCheckedChanged
を使います
1 2 3 4 5 6 7 8 9 10 11 |
@SuppressLint("UseSwitchCompatOrMaterialCode") Switch sw = findViewById(R.id.switch0); sw.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { // The toggle is enabled } else { // The toggle is disabled } } }); |
ここでも、@SuppressLint(“UseSwitchCompatOrMaterialCode”)をいれるようにwarningが出ます
サンプルコード
よく設定にあるSwithボタンでAirPlaneモードに入ると
それにより他の通信がOFFになるような設定を考えてみます
(UseSwitchCompatOrMaterialCodeが山ほど出ています…)
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
//package com.example.testswitch; import android.annotation.SuppressLint; import android.os.Bundle; import android.util.Log; import android.widget.Switch; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.activity_main); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); @SuppressLint("UseSwitchCompatOrMaterialCode") Switch sw0 = findViewById(R.id.switch0); @SuppressLint("UseSwitchCompatOrMaterialCode") Switch sw1 = findViewById(R.id.switch1); @SuppressLint("UseSwitchCompatOrMaterialCode") Switch sw2 = findViewById(R.id.switch2); @SuppressLint("UseSwitchCompatOrMaterialCode") Switch sw3 = findViewById(R.id.switch3); sw1.setChecked(true); sw2.setChecked(true); sw3.setChecked(true); // lambda式にしたので、OnCheckedChangeListener()は見えなくなっています sw0.setOnCheckedChangeListener((buttonView, isChecked) -> { if (isChecked) { Log.d("debug","The Switch is enabled"); sw1.setChecked(false); sw2.setChecked(false); sw3.setChecked(false); } else { Log.d("debug","The Switch is disabled"); } }); } } |
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
<?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/main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Switch android:id="@+id/switch0" android:layout_width="200dp" android:layout_height="50dp" android:padding="15dp" android:text="@string/sw0" android:background="#ccffee" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.1" tools:ignore="UseSwitchCompatOrMaterialXml" /> <Switch android:id="@+id/switch1" android:layout_width="200dp" android:layout_height="50dp" android:padding="15dp" android:text="@string/sw1" android:background="#ccffee" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.2" tools:ignore="UseSwitchCompatOrMaterialXml" /> <Switch android:id="@+id/switch2" android:layout_width="200dp" android:layout_height="50dp" android:padding="15dp" android:text="@string/sw2" android:background="#ccffee" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.3" tools:ignore="UseSwitchCompatOrMaterialXml" /> <Switch android:id="@+id/switch3" android:layout_width="200dp" android:layout_height="50dp" android:padding="15dp" android:text="@string/sw3" android:background="#ccffee" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.4" tools:ignore="UseSwitchCompatOrMaterialXml" /> </androidx.constraintlayout.widget.ConstraintLayout> |
strings.xml
1 2 3 4 5 6 7 |
<resources> <string name="app_name">TestSwitch</string> <string name="sw0">AirPlane mode: </string> <string name="sw1">WiFi</string> <string name="sw2">Bluetooth</string> <string name="sw3">Phone</string> </resources> |
実行してみると
thumbとtrackのカスタマイズ
Switchでのthumbとtrackの色と形をカスタマイズするには
shape を使うことで可能です
ただ、これはボタンのようなON/OFFの状態遷移があるので
selectorを使ってstateに応じて色と形を変化させます
SwitchではMaterialに関係しない部分は
同様のことがSwitchCompatでもできます
custom_thumb_selector.xml
custom_track_selector.xml
のxmlファイルを作成してdrawable以下に配置します
このようなthumbとtrackでカスタマイズしてみます
shapeはrectagleで四角形
corners のradiusの分だけ角丸になります
soildでは色と縦横サイズを設定
- デフォルト:android:state_enabled=”false”
- チェック後:android:state_checked=”true”
状態としてはpressedなどありますが省略します
custom_thumb_selector.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false"> <shape android:shape="rectangle"> <stroke android:width="2dp" android:color="#484"/> <solid android:color="#4e4"/> <size android:width="30dp" android:height="30dp" /> <corners android:radius="5dp"/> </shape> </item> <item android:state_checked="true"> <shape android:shape="rectangle"> <stroke android:width="2dp" android:color="#484"/> <solid android:color="#fe4"/> <size android:width="30dp" android:height="30dp" /> <corners android:radius="5dp"/> </shape> </item> </selector> |
custom_track_selector.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false"> <shape android:shape="rectangle"> <stroke android:width="2dp" android:color="#444"/> <solid android:color="#8b8"/> <corners android:radius="5dp"/> </shape> </item> <item android:state_checked="true"> <shape android:shape="rectangle"> <stroke android:width="2dp" android:color="#444"/> <solid android:color="#bdb"/> <corners android:radius="5dp"/> </shape> </item> </selector> |
それぞれのselectorをレイアウトに設定します
android:thumb=”@drawable/custom_thumb_selector” android:track=”@drawable/custom_track_selector”
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?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" tools:context=".MainActivity"> <Switch android:layout_width="wrap_content" android:layout_height="wrap_content" android:thumb="@drawable/custom_thumb_selector" android:track="@drawable/custom_track_selector" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.45" tools:ignore="UseSwitchCompatOrMaterialXml" /> <Switch android:layout_width="wrap_content" android:layout_height="wrap_content" android:thumb="@drawable/custom_thumb_selector" android:track="@drawable/custom_track_selector" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.55" tools:ignore="UseSwitchCompatOrMaterialXml" /> </androidx.constraintlayout.widget.ConstraintLayout> |
実行してみると
References:
切り替えボタン | Android デベロッパー
Switch – Android Developers