RelativeLayout 本身不支援 state_pressed 等狀態,因此直接在 XML 定義 selector 無法讓內部 TextView、ImageView 聯動變色。
public class SelectableRelativeLayout extends RelativeLayout {
public SelectableRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
setClickable(true); // 關鍵:啟用點擊事件傳遞
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
// 將狀態分發給子 View
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.setPressed(isPressed());
child.setSelected(isSelected());
child.setActivated(isActivated());
}
}
}
XML 使用:
<com.example.SelectableRelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_selector">
<TextView ... android:textColor="@color/text_selector" />
<ImageView ... android:src="@drawable/arrow_selector" />
</com.example.SelectableRelativeLayout>
layout.setOnClickListener(v -> {
textView.setTextColor(Color.RED);
imageView.setColorFilter(Color.RED);
// 執行業務邏輯
new Handler().postDelayed(() -> {
textView.setTextColor(Color.BLACK);
imageView.clearColorFilter();
}, 200);
});
<!-- res/color/text_selector.xml -->
<selector xmlns:android="https://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="@color/red" />
<item android:color="@color/black" />
</selector>
<!-- res/drawable/arrow_selector.xml -->
<selector xmlns:android="https://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/arrow_red" />
<item android:drawable="@drawable/arrow_black" />
</selector>
MaterialButton 或 Chip內建支援狀態變色、圖標、文字,無需自定義 Layout。
RelativeLayout 無原生狀態,需自定義 ViewGroup 分發狀態或手動控制子 View 外觀。推薦方案一封裝性最佳,方案二適合快速原型,方案三利用現成 Material 元件最省力。