Gestures trong android

Khi phát triển một ứng dụng android chắc hẳn các bạn đã quá quen thuộc với những sự kiện Touch màn hình, đó là những thao tác của người dùng để tương tác với ứng dụng của bạn. Trong android có cung cấp cho chúng ta rất nhiều kiểu sự kiện touch màn hình như những thao tác vuốt, kéo, thả, chạm ... chúng được gọi là gesture, cùng với đó là những api cho phép chúng ta xác định được những loại sự kiện touch màn hình nào đang xảy ra để từ đó thực hiện sử xý những sự kiện theo ý muốn .

Để detect gesture Android cung cấp lớp GestureDetector để thu nhận các sự kiện di chuyển và nói cho chúng ta rằng các sự kiện này tương ứng với các Gesture hoặc không. Để sử dụng nó, bạn cần tạo một đối tượng GestureDetector và sau đó kế thừa lớp khác với GestureDetector. SimpleOnGestureListener để hoạt động như là một Listener và ghi đè một số phương thức. Sau đây mình xin giới thiệu với các bạn cách phát hiện và xử lý những sự kiện touch màn hình thông dụng trong android.

Như đã nhắc đến ở trên chúng ta sử dụng GestureDetector và implement các phuơng thức của SimpleOnGestureListener để phát hiện và sử lý khi gesture xảy ra, tuy nhiên chúng ta nên sử dụng lớp GestureDetectorCompat và MotioneventCompat, chúng là nhưng class năm trong thư viện Suppport Library. Các class ở trong Support Library được cung cấp để có thể hỗ trợ tương thích với các phiên bản android từ 1.6 trở lên. Chú ý rằng class MotionEventCompat không thay thế cho class MonitonEvent mà nó chỉ cung cấp thêm các tiện ích mà class MonitonEvent không có.

Khi bạn khởi tạo một đối tượng GestureDetectorCompat để detect gesture cho view hoặc Activity thì một trong những việc làm đầu tiên tại View hoặc Activity là bạn phải implement GestureDetector.OnGestureListener để thông báo cho người dùng khi một Touch event đặc biệt đã xảy ra.

public class MainActivity extends Activity implements
        GestureDetector.OnGestureListener,
        GestureDetector.OnDoubleTapListener{

    private static final String DEBUG_TAG = "Gestures";
    private GestureDetectorCompat mDetector;

    // Called when the activity is first created.
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Instantiate the gesture detector with the
        // application context and an implementation of
        // GestureDetector.OnGestureListener
        mDetector = new GestureDetectorCompat(this,this);
        // Set the gesture detector as the double tap
        // listener.
        mDetector.setOnDoubleTapListener(this);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        this.mDetector.onTouchEvent(event);
        // Be sure to call the superclass implementation
        return super.onTouchEvent(event);
    }

    @Override
    public boolean onDown(MotionEvent event) {
        Log.d(DEBUG_TAG,"onDown: " + event.toString());
        return true;
    }

    @Override
    public boolean onFling(MotionEvent event1, MotionEvent event2,
            float velocityX, float velocityY) {
        Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());
        return true;
    }

    @Override
    public void onLongPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onLongPress: " + event.toString());
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
            float distanceY) {
        Log.d(DEBUG_TAG, "onScroll: " + e1.toString()+e2.toString());
        return true;
    }

    @Override
    public void onShowPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onShowPress: " + event.toString());
    }

    @Override
    public boolean onSingleTapUp(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString());
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString());
        return true;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());
        return true;
    }
}

GestureDetector.OnGestureListener chứa rất nhiều các callback định nghĩa cho các gesture tương ứng như onLongPress(), onScroll(), onFling(), .... . Tuy nhiên khi bạn muốn sử lý với một số sự kiện đơn giản thì bạn chỉ cần sử dụng GestureDetector.SimpleOnGestureListener thay cho việc implement cả interface GestureDetector.OnGestureListener có rất nhiều hàm. Class GestureDetector.SimpleOnGestureListener đã implement tất cả các hàm có trong GestureDetector.OnGestureListener và trả về false. nếu bạn muốn custom sự kiện gì thì bạn có thể override hàm đó và custom. ví dụ như đoạn code dưới tôi đã override lại 2 hàm là onDown và onFling

public class MainActivity extends Activity {

    private GestureDetectorCompat mDetector;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDetector = new GestureDetectorCompat(this, new MyGestureListener());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        this.mDetector.onTouchEvent(event);
        return super.onTouchEvent(event);
    }

    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
        private static final String DEBUG_TAG = "Gestures";

        @Override
        public boolean onDown(MotionEvent event) {
            Log.d(DEBUG_TAG,"onDown: " + event.toString());
            return true;
        }

        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2,
                float velocityX, float velocityY) {
            Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());
            return true;
        }
    }
}

Chúng ta có thể phát hiện và sử lý với những gesture mà android cung cấp sẵn, vậy câu hỏi đặt ra là liệu rằng chúng ta có thể tự định nghĩa một gesture như gesture tạo một ngôi sao hay vẽ hình tròn ... câu trả lời là có . Chung ta hoàn toàn có thể làm được điều này, đã có những ứng dụng khóa màn hình bằng gesture và nó đang sử dụng cách này . Trong bài viết tiếp theo mình sẽ giới thiệu đến các bạn việc tạo và so sánh gesture

Tham khảo: https://developer.android.com/training/gestures/detector.html