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

วิธีใช้ Action Down Event (การกดลง) ใน Android

ภาพรวม

ตัวอย่างนี้สาธิตการจับเหตุการณ์ MotionEvent.ACTION_DOWN ซึ่งเกิดขึ้นเมื่อผู้ใช้สัมผัสหน้าจอ (Touch down) ใช้สำหรับการตรวจจับการกด ต่างจาก OnClickListener ที่รอจนกว่าจะปล่อย (Action Up)

ขั้นตอนการสร้างโปรเจกต์

ขั้นตอนที่ 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:app="https://schemas.android.com/apk/res-auto"
    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">

    <TextView
        android:id="@+id/actionEvent"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginTop="30dp"
        android:textSize="40sp"
        android:gravity="center"
        android:text="กดที่นี่"
        android:background="#E0E0E0"
        android:padding="20dp" />

</LinearLayout>

ขั้นตอนที่ 3: โค้ดหลัก (src/MainActivity.java)

package com.example.myapplication;

import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    TextView textView;

    @SuppressLint("ClickableViewAccessibility")
    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView actionEvent = findViewById(R.id.actionEvent);
        actionEvent.setText("Action Down Test");
        
        actionEvent.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // ใช้ MotionEventCompat เพื่อรองรับ Multi-touch
                int action = MotionEventCompat.getActionMasked(event);
                
                if (action == MotionEvent.ACTION_DOWN) {
                    // เกิดขึ้นทันทีเมื่อสัมผัสหน้าจอ
                    Toast.makeText(MainActivity.this, "Action DOWN - กดลงแล้ว", Toast.LENGTH_SHORT).show();
                    actionEvent.setText("สถานะ: กดลง (DOWN)");
                    actionEvent.setBackgroundColor(0xFF4CAF50); // สีเขียว
                    return true; // Consume event
                }
                
                return false; // ให้ระบบจัดการต่อ
            }
        });
    }
}

MotionEvent Action Types

Action Constantคำอธิบายลำดับ
ACTION_DOWNPointer แรกสัมผัสหน้าจอ (เริ่ม Gesture)1
ACTION_POINTER_DOWNPointer เพิ่มเติมสัมผัส (Multi-touch)2+
ACTION_MOVEPointer เคลื่อนที่บนหน้าจอซ้ำหลายครั้ง
ACTION_POINTER_UPPointer เพิ่มเติมปล่อย (Multi-touch)-
ACTION_UPPointer สุดท้ายปล่อย (จบ Gesture)สุดท้าย
ACTION_CANCELGesture ถูกยกเลิก (โดยระบบ)-

Action Down vs OnClickListener

คุณสมบัติOnTouchListener (ACTION_DOWN)OnClickListener
เวลาทำงานทันทีเมื่อสัมผัสเมื่อปล่อย (Down + Up ในพื้นที่เดียวกัน)
Drag/Scrollจับได้ตอนกดไม่ทำงานถ้าลาก
Long Pressแยกได้ชัดเจนมี OnLongClickListener แยก
Multi-touchรองรับ (Pointer ID)ไม่รองรับโดยตรง
Visual Feedbackต้องจัดการเองมี Ripple/Background อัตโนมัติ

กรณีการใช้งาน ACTION_DOWN

  • Game Controls: ปุ่มควบคุมเกมที่ต้องตอบสนองทันที
  • Drawing Apps: เริ่มวาดทันทีเมื่อสัมผัส
  • Custom Buttons: ปุ่มที่มี Visual feedback ทันที
  • Drag & Drop: เริ่ม Drag operation
  • Instrument Apps: Piano, Drum - เสียงต้องออกทันที

ข้อควรระวัง

  • ต้อง return true ใน ACTION_DOWN เพื่อบอกระบบว่า Consume event แล้ว (จะได้รับ MOVE, UP ต่อ)
  • หาก return false จะไม่ได้รับ Event ต่อไป (MOVE, UP)
  • ใช้ MotionEventCompat.getActionMasked() สำหรับ Multi-touch compatibility
  • จัดการ ACTION_CANCEL สำหรับกรณีระบบยกเลิก (เช่น Dialog ปิดทับ)
  • สำหรับ View ธรรมดา ควรใช้ setClickable(true) และ Background selector

ตัวอย่างปุ่มกดที่มี Visual Feedback

button.setOnTouchListener((v, event) -> {
    switch (event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN:
            v.setBackgroundColor(0xFF4CAF50); // สีเข้มตอนกด
            v.setScaleX(0.95f); v.setScaleY(0.95f); // ย่อเล็กนิด
            return true;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            v.setBackgroundColor(0xFF2196F3); // สีปกติ
            v.setScaleX(1f); v.setScaleY(1f);
            if (event.getActionMasked() == MotionEvent.ACTION_UP) {
                performClick(); // เรียก OnClickListener
            }
            return true;
        case MotionEvent.ACTION_MOVE:
            // ตรวจสอบว่าอยู่ใน bounds หรือไม่
            if (!isPointInView(v, event.getX(), event.getY())) {
                v.setBackgroundColor(0xFF2196F3);
                v.setScaleX(1f); v.setScaleY(1f);
            }
            return true;
    }
    return false;
});