Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

สร้างปุ่ม Android แบบกำหนดสีเองด้วย Drawable Selector

บทความนี้สาธิตวิธีสร้างปุ่ม (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>

การทดสอบ

  1. รันแอป จะเห็นปุ่มสีฟ้าไล่สี (Default)
  2. กดค้าง จะเห็นสีเหลืองไล่สี (Pressed)
  3. ใช้คีย์บอร์ด/DPad นำทาง จะเห็นสีส้มไล่สี (Focused)
  4. ลอง button.setEnabled(false) จะเห็นสีเทา (Disabled)
เคล็ดลับ: ใช้ android:backgroundTint กับ Button ธรรมดา (API 21+) สำหรับการเปลี่ยนสีพื้นหลังแบบง่าย ไม่ต้องทำ Selector shape ทั้งอัน