Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách tùy chỉnh giao diện (Style) cho Switch widget trên Android

Giới thiệu

Bài viết hướng dẫn tùy chỉnh giao diện Switch (công tắc bật/tắt) trên Android bằng file XML drawable: thay đổi màu thumb, track, bo góc, gradient, viền cho 2 trạng thái ON/OFF.

Các bước thực hiện

Bước 1: Tạo dự án mới

Android Studio → File → New Project → Empty Activity.

Bước 2: Layout chính (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:id="@+id/relativeLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="4dp"
    tools:context=".MainActivity">

    <Switch
        android:id="@+id/switchBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textOn="BẬT"
        android:textOff="TẮT"
        android:thumb="@drawable/custom_switch_selector"
        android:track="@drawable/custom_track" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/switchBtn"
        android:layout_marginTop="20dp"
        android:text="Vuốt Switch BẬT/TẮT"
        android:textSize="24sp"
        android:textAlignment="center"
        android:textStyle="bold" />
</RelativeLayout>

Bước 3: Drawable Selector cho Thumb (res/drawable/custom_switch_selector.xml)

Định nghĩa hình ảnh thumb cho 2 trạng thái checked/unchecked.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="https://schemas.android.com/apk/res/android">
    <!-- Trạng thái BẬT (checked) -->
    <item android:state_checked="true">
        <shape android:shape="rectangle"
            android:dither="true"
            android:useLevel="false"
            android:visible="true">
            <corners android:radius="15dp" />
            <gradient
                android:angle="270"
                android:startColor="#66AAFF00"
                android:endColor="#6600FF00" />
            <size android:width="37dp" android:height="37dp" />
            <stroke android:width="4dp" android:color="#0000FF" />
        </shape>
    </item>

    <!-- Trạng thái TẮT (unchecked) -->
    <item android:state_checked="false">
        <shape android:shape="rectangle"
            android:dither="true"
            android:useLevel="false"
            android:visible="true">
            <corners android:radius="15dp" />
            <gradient
                android:angle="270"
                android:startColor="#FF0000"
                android:endColor="#FF0000" />
            <size android:width="37dp" android:height="37dp" />
            <stroke android:width="4dp" android:color="#0000FF" />
        </shape>
    </item>
</selector>

Bước 4: Drawable cho Track (res/drawable/custom_track.xml)

Track là thanh nền trượt của switch.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="https://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    android:visible="true"
    android:dither="true"
    android:useLevel="false">

    <gradient
        android:startColor="#27170432"
        android:endColor="#27170432"
        android:angle="270" />

    <corners android:radius="15dp" />
    <size android:width="80dp" android:height="40dp" />
</shape>

Bước 5: Logic (src/MainActivity.java)

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    Switch aSwitch;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        aSwitch = findViewById(R.id.switchBtn);
        aSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
            if (isChecked) {
                Toast.makeText(MainActivity.this, "Switch BẬT", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(MainActivity.this, "Switch TẮT", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

Bước 6: Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.sample">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Chạy ứng dụng

Kết nối thiết bị, nhấn Run. Vuốt switch → thumb chuyển động với gradient xanh (ON) / đỏ (OFF), track xám bo tròn.

Cách tùy chỉnh giao diện (Style) cho Switch widget trên Android

Giải thích các thuộc tính Drawable

Thuộc tínhChức năng
android:state_checkedSelector chọn item dựa trên trạng thái checked
<shape>Hình dạng: rectangle, oval, line, ring
<corners android:radius>Bo góc (dp)
<gradient>Độ dốc màu: startColor, endColor, angle, centerX/Y, type (linear/radial/sweep)
<size>Kích thước width/height (dp)
<stroke>Viền: width, color, dashWidth/dashGap
android:ditherDithering cho gradient mượt hơn

Cách hiện đại: Material Components Switch

Từ Material Components 1.1.0+, dùng MaterialSwitch (tự động Material Design 3):

<com.google.android.material.switchmaterial.SwitchMaterial
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textOn="ON"
    android:textOff="OFF"
    app:trackColor="@color/switch_track_color_selector"
    app:thumbColor="@color/switch_thumb_color_selector"
    app:thumbIcon="@drawable/ic_check" />

Color Selector (res/color/switch_track_color_selector.xml)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="https://schemas.android.com/apk/res/android">
    <item android:color="@color/colorPrimary" android:state_checked="true" />
    <item android:alpha="0.38" android:color="@color/colorOnSurface" android:state_checked="false" />
    <item android:color="@color/colorOnSurface" /> <!-- disabled -->
</selector>

So sánh

Lưu ý

  • Kích thước thumb/track nên cân đối (thumb nhỏ hơn track ~2-4dp)
  • Test trên nhiều kích thước màn hình (dp scale)
  • Accessibility: Đảm bảo contrast ratio ≥ 4.5:1
  • RTL: Switch tự động flip trên locale RTL
CáchƯu điểmNhược điểm
Drawable XML (bài này)Tùy chỉnh hoàn toàn hình dạng, gradient, viềnPhức tạp, nhiều file, khó maintain
MaterialSwitch + ColorSelectorTuân thủ Material Design, ít code, hỗ trợ Motion, rippleÍt tùy chỉnh hình dạng thumb (chỉ tròn/bo tròn)
Jetpack Compose SwitchDeclarative, state-driven, preview realtimeYêu cầu migrate sang Compose