Поддержка мультитач Android - PullRequest
6 голосов
/ 21 апреля 2010

Интересно, надежна ли поддержка мультитач Android? Я прочитал это страдает от некоторых проблем.

Мне также интересно, как я могу определить собственные мультитач-жесты? Как: 3 пальца вращаются или 3 пальца остаются неподвижными, а четвертый двигается.

Я сталкивался с некоторыми ресурсами (Gestures или MotionEvent на developer.android.com), но ничто не говорит об этом четко.

С уважением,

Зденек

1 Ответ

11 голосов
/ 21 апреля 2010

Я покопался в API и нашел способ выполнять жесты, такие как пинч / реверс пинч, поэтому я считаю, что жесты, которые вы описываете, возможны - нужно просто разобраться, как их кодировать. Ниже я вставил пример обратного пинча, который я реализовал. Я хотел, чтобы щепотка регистрировалась, только если она ориентирована горизонтально. Это не очень чистый или многократно используемый код, но он должен помочь вам двигаться вперед. Работает на Android 2.0.x. Я читал Multi-Touch может иметь проблемы в более ранних версиях. Примером является класс, который я вызываю из onTouchEvent действия, перенаправляя событие в класс.

public class HorizontalReversePinchDetector {

    public boolean onTouchEvent(MotionEvent e) {

        int pointerCount = e.getPointerCount();

        if(pointerCount != 2) {
            Log.d(GESTURE, "not pinching - exactly 2 fingers are needed but have " + pointerCount);
            clearPinch();
            return false;
        }

        int firstIndex = e.getX(0) < e.getX(1) ? 0: 1;
        int secondIndex = e.getX(0) < e.getX(1) ? 1: 0;

        Finger currentLeftFinger = new Finger(e.getX(firstIndex), e.getY(firstIndex));
        Finger currentRightFinger = new Finger(e.getX(secondIndex), e.getY(secondIndex));

        float yDifference = Math.abs(currentLeftFinger.getY() - currentRightFinger.getY());
        if(yDifference > 80) {
            Log.d(GESTURE, "not pinching - fingers too vertically-oriented");
            clearPinch();
            return false;
        }

        if(initialLeftFinger == null) {
            initialLeftFinger = currentLeftFinger;
            initialRightFinger = currentRightFinger;
            Log.d(GESTURE, "not pinching, but might be starting a pinch...");
            return false;
        }

        float leftFingerDistance = initialLeftFinger.getX() - currentLeftFinger.getX();
        float rightFingerDistance = currentRightFinger.getX() - initialRightFinger.getX();

        float xDistanceBetweenFingers = Math.abs(currentLeftFinger.getX() - currentRightFinger.getX());
        if(xDistanceBetweenFingers < minimumDistanceBetweenFingers) {
            Log.d(GESTURE, "pinching, but fingers are not far enough apart...");
            return true;
        }

        if(leftFingerDistance < minimumDistanceForEachFinger) {
            Log.d(GESTURE, "pinching, but left finger has not moved enough...");
            return true;
        }
        if(rightFingerDistance < minimumDistanceForEachFinger) {
            Log.d(GESTURE, "pinching, but right finger has not moved enough...");
            return true;
        }

        pinchCompleted();
        return true;
    }

    private void pinchCompleted() {
        Log.d(GESTURE, "pinch completed");
        if(pinchListener != null) pinchListener.onPinch();
        clearPinch();
    }

    public static interface OnPinchListener {
        void onPinch();
    }

    private void clearPinch() {
        initialLeftFinger = null;
        initialRightFinger = null;
    }

    public void setPinchListener(OnPinchListener pinchListener) {
        this.pinchListener = pinchListener;
    }

    private static class Finger {

        private Finger(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public float getX() {
            return x;
        }

        public float getY() {
            return y;
        }

        private float x;
        private float y;
    }

    private Finger initialLeftFinger;
    private Finger initialRightFinger;
    private OnPinchListener pinchListener;
    private static final float minimumDistanceForEachFinger = 30;
    private static final float minimumDistanceBetweenFingers = 50;
}

Что касается надежности, этот код был полностью надежным. Опять же, только на Android 2.0.x. Я не тестировал его на других версиях платформы.

...