บทความนี้สาธิตวิธีสร้างปุ่ม (Button) ที่มีสีเปลี่ยนตามสถานะ (State) โดยใช้ Drawable Selector ใน XML ไม่ต้องเขียนโค้ด Java/Kotlin เพิ่มเติม
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
Android Studio → File → New Project → Empty Activity
ขั้นตอนที่ 2: Layout หลัก (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<Button
android:id="@+id/customButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ปุ่มสีพิเศษ"
android:textSize="18sp"
android:padding="16dp"
android:background="@drawable/btn_custom_selector" />
</LinearLayout>
ขั้นตอนที่ 3: สร้าง Drawable Selector (res/drawable/btn_custom_selector.xml)
ไฟล์นี้คือหัวใจของการเปลี่ยนสีตามสถานะ
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="https://schemas.android.com/apk/res/android">
<!-- สถานะกดอยู่ (Pressed) -->
<item android:state_pressed="true">
<shape android:shape="rectangle">
<gradient
android:startColor="#FFFF00"
android:endColor="#D9DD95"
android:angle="270" />
<stroke
android:width="3dp"
android:color="#D1D3E3" />
<corners android:radius="8dp" />
<padding
android:left="16dp"
android:top="12dp"
android:right="16dp"
android:bottom="12dp" />
</shape>
</item>
<!-- สถานะโฟกัส (Focused) - เช่น ใช้คีย์บอร์ด/DPad นำทาง -->
<item android:state_focused="true">
<shape android:shape="rectangle">
<gradient
android:startColor="#ECA680"
android:endColor="#FD5900"
android:angle="270" />
<stroke
android:width="3dp"
android:color="#D1D3E3" />
<corners android:radius="8dp" />
<padding
android:left="16dp"
android:top="12dp"
android:right="16dp"
android:bottom="12dp" />
</shape>
</item>
<!-- สถานะปกติ (Default/Enabled) -->
<item android:state_enabled="true">
<shape android:shape="rectangle">
<gradient
android:startColor="#A1AAEE"
android:endColor="#4356E7"
android:angle="270" />
<stroke
android:width="2dp"
android:color="#D1D3E3" />
<corners android:radius="8dp" />
<padding
android:left="16dp"
android:top="12dp"
android:right="16dp"
android:bottom="12dp" />
</shape>
</item>
<!-- สถานะปิดใช้งาน (Disabled) -->
<item android:state_enabled="false">
<shape android:shape="rectangle">
<solid android:color="#CCCCCC" />
<stroke
android:width="1dp"
android:color="#999999" />
<corners android:radius="8dp" />
<padding
android:left="16dp"
android:top="12dp"
android:right="16dp"
android:bottom="12dp" />
</shape>
</item>
</selector>
ขั้นตอนที่ 4: MainActivity.java (Optional - สาธิตการเปลี่ยนสถานะ)
package com.example.custombutton;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button customButton;
private boolean isEnabled = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customButton = findViewById(R.id.customButton);
customButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "กดปุ่มสำเร็จ!", Toast.LENGTH_SHORT).show();
}
});
// ปุ่มทดสอบสถานะ Disabled (เพิ่มใน Layout ถ้าต้องการ)
// Button toggleBtn = findViewById(R.id.toggleBtn);
// toggleBtn.setOnClickListener(v -> {
// isEnabled = !isEnabled;
// customButton.setEnabled(isEnabled);
// });
}
}
🎨 อธิบายองค์ประกอบ Drawable Selector
| Attribute | คำอธิบาย | ค่าตัวอย่าง |
|---|---|---|
state_pressed |
เมื่อผู้ใช้กดค้างอยู่ | true / false |
state_focused |
เมื่อได้รับโฟกัส (Keyboard navigation) | true / false |
state_enabled |
สถานะเปิด/ปิดใช้งาน | true / false |
state_selected |
สถานะถูกเลือก (เช่น Tab, CheckBox) | true / false |
state_checked |
สถานะติ๊กถูก (CheckBox, RadioButton) | true / false |
state_hovered |
เมื่อเมาส์ชี้อยู่ (Chrome OS, Desktop) | true / false |
🔧 Shape Elements (รูปร่าง)
- <solid> - สีทึบ (Single color)
- <gradient> - ไล่สี (startColor, endColor, angle, type="linear|radial|sweep")
- <stroke> - ขอบ (width, color, dashWidth, dashGap)
- <corners> - มุมโค้ง (radius, topLeftRadius, bottomRightRadius, etc.)
- <padding> - ระยะห่างภายใน (left, top, right, bottom)
💡 แนวทางทันสมัย: MaterialButton (Material Components)
แนะนำให้ใช้ com.google.android.material.button.MaterialButton ซึ่งรองรับ Theme และ Style อย่างเต็มที่:
<!-- build.gradle -->
implementation "com.google.android.material:material:1.11.0"
<!-- Layout -->
<com.google.android.material.button.MaterialButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Material Button"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
app:backgroundTint="@color/custom_color_selector"
app:strokeColor="@color/stroke_selector"
app:cornerRadius="8dp" />
สร้าง Color Selector (res/color/btn_color_selector.xml):
<selector xmlns:android="https://schemas.android.com/apk/res/android">
<item android:color="#FFFF00" android:state_pressed="true" />
<item android:color="#FD5900" android:state_focused="true" />
<item android:color="#4356E7" android:state_enabled="true" />
<item android:color="#CCCCCC" android:state_enabled="false" />
</selector>
การทดสอบ
- รันแอป จะเห็นปุ่มสีฟ้าไล่สี (Default)
- กดค้าง จะเห็นสีเหลืองไล่สี (Pressed)
- ใช้คีย์บอร์ด/DPad นำทาง จะเห็นสีส้มไล่สี (Focused)
- ลอง
button.setEnabled(false)จะเห็นสีเทา (Disabled)
เคล็ดลับ: ใช้ android:backgroundTint กับ Button ธรรมดา (API 21+) สำหรับการเปลี่ยนสีพื้นหลังแบบง่าย ไม่ต้องทำ Selector shape ทั้งอัน