`GridView` 中 `ImageButton` 使用 `android:src="@drawable/on"` (因 `background` 會拉伸變形)。點擊後圖片**重疊、變形**,狀態切換異常。
**棄用 `src`,改用 `background` 搭配 `scaleType` 無效的問題,用 9-patch (.9.png) 或 XML `inset` 解決拉伸**。
<selector xmlns:android="https://schemas.android.com/apk/res/android">
<!-- 按下狀態 -->
<item android:state_pressed="true" android:drawable="@drawable/voice_on_do" />
<!-- 聚焦狀態 (鍵盤/手柄導航) -->
<item android:state_focused="true" android:drawable="@drawable/voice_on_do" />
<!-- 正常狀態 -->
<item android:drawable="@drawable/voice_on_unpress" />
</selector>
**順序原則**:具體狀態在前,通用預設狀態在後 (無任何 `state_*` 屬性)。
<ImageButton
android:id="@+id/search_voice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/btn_selector"
android:scaleType="centerInside" />
<!-- scaleType 對 background 無效,見下文 -->
**根治 `background` 拉伸變形的唯一標準方法是 .9.png (NinePatch)。**
若不需要按下視覺反饋,直接用 `ImageView` + `setOnClickListener`,`src` + `scaleType="centerInside"` 完美保持比例,最簡單。
searchVoice.setOnClickListener(v -> {
flag = !flag;
// 狀態由 Selector 自動管理,無需手動 setBackgroundResource
Toast.makeText(this, flag ? "語音開啟" : "語音屏蔽", Toast.LENGTH_SHORT).show();
// 若需程式碼切換狀態:v.setPressed(flag); 或 v.setSelected(flag);
});
**ImageButton 圖片變形/重疊核心在於 `background` 拉伸與 Selector 定義錯誤。** 標準解法:**正確編寫 Selector (狀態順序、無重複) + 使用 .9.png 九宮格圖片解決背景拉伸**。若不需要按鈕狀態,改用 `ImageView` + `src` + `scaleType` 最省事。