在 Android 開發中,為了提升用戶體驗,我們經常需要根據 View(如 Button、ListView 項目)的不同狀態(按下、聚焦、選中、不可用等)顯示不同的背景圖片或顏色。若在代碼中手動監聽狀態變化並切換背景,不僅繁瑣且難以維護。Android 提供了 Selector (狀態列表可繪製對象) 機制,通過 XML 聲明式配置即可輕鬆實現狀態與背景的自動映射。本文將系統講解 Selector 的屬性、結構及實戰用法。
Selector 根節點為 <selector>,包含多個 <item> 子節點,每個 item 通過屬性指定適用的狀態組合。常用屬性如下:
| 屬性 | 說明 | 典型值 |
|---|---|---|
android:state_pressed | 是否處於按下狀態 | true / false |
android:state_focused | 是否獲得焦點 (如方向鍵/轨迹球導航) | true / false |
android:state_selected | 是否被選中 (如 Tab 選中、ListView 項目選中) | true / false |
android:state_checked | 可勾選組件 (CheckBox/RadioButton) 是否勾選 | true / false |
android:state_checkable | 組件是否可勾選 | true / false |
android:state_enabled | 組件是否可用 (能否接收點擊/觸摸事件) | true / false |
android:state_window_focused | 應用程式窗口是否有焦點 (應用在前台) | true / false |
android:state_active | 常用於 SlidingDrawer 等,表示激活狀態 | true / false |
android:drawable | 指定該狀態下的背景資源 (圖片/顏色/形狀) | @drawable/xxx |
關鍵匹配規則:系統按 <item> 定義順序從上到下匹配,**第一個匹配當前狀態組合的 item 將被使用**。因此,**默認狀態 (無任何 state_* 屬性) 必須放在最後**,作為兜底。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="https://schemas.android.com/apk/res/android">
<!-- 勾選狀態:燈亮 -->
<item android:state_checked="true" android:drawable="@drawable/r7" />
<!-- 未勾選狀態:燈滅 -->
<item android:state_checked="false" android:drawable="@drawable/r7b" />
<!-- 默認狀態 (兜底) -->
<item android:drawable="@drawable/r7b" />
</selector>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@null" <!-- 隱藏默認勾選框圖標 -->
android:drawableTop="@drawable/bg_button" <!-- 設置 Selector 作為頂部圖片 -->
android:text="燈"
android:textSize="15sp"
android:textColor="#EE2C2C" />
checked=true/false 間切換。state_checked 切換顯示 r7 (亮燈) 或 r7b (滅燈) 圖片。可同時指定多個狀態屬性實現精細控制。例如:按下且未禁用 時顯示深色背景:
<item android:state_pressed="true" android:state_enabled="true" android:drawable="@drawable/btn_pressed" />
<item android:state_enabled="false" android:drawable="@drawable/btn_disabled" />
<item android:drawable="@drawable/btn_normal" />
任何繼承自 View 的組件均可通過 android:background 設置 Selector。但需注意:TextView 默認不處理點擊事件,需設置 android:clickable="true" 或 setOnClickListener 才能觸發 state_pressed。
若僅需切換文字顏色或背景純色,可使用 ColorStateList (res/color/xxx.xml),結構類似 Selector 但 <item> 使用 android:color 屬性。
ShapeDrawable (shape 標籤) 定義形狀、漸變、描邊,減少圖片體積。Selector 是 Android 實現視圖狀態視覺反饋的基石組件。掌握其聲明式配置、順序匹配規則及狀態屬性組合,能讓你以極低成本構建交互豐富、體驗流暢的界面。實際開發中,建議將通用狀態背景 (如按鈕通用樣式) 封裝為基礎 Selector,項目層復用,保持風格統一且易維護。