GestureDetector.SimpleOnGestureListener и GestureDetectorCompat не работают. Что не так с моим кодом?

Я следую руководству по обнаружению распространенных жестов. Я связался с библиотекой android-support-v4.jar, чтобы получить GestureDetectorCompat, и мой код выглядит точно так же, как в руководстве, за исключением того, что я обнаруживаю жесты в своем пользовательском представлении, а не в действии:

public class MyGlView extends GLSurfaceView {

    private GestureDetectorCompat m_gestureDetector = null;

    public MyGlView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }
    public MyGlView(Context context) {
        super(context);
        init(context);
    }
    private void init(Context context) {
        if (m_gestureDetector == null)
            m_gestureDetector = new GestureDetectorCompat(context, new MyGestureListener());

        setEGLContextClientVersion(2);
        setRenderer(new DrawSurfRenderer());
        setRenderMode(RENDERMODE_CONTINUOUSLY); 
    }

@Override
    public boolean onTouchEvent(MotionEvent event) {

        m_gestureDetector.onTouchEvent(event);      
        return super.onTouchEvent(event);
    }

public class MyGestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
        {
            Log.e("", "OnScroll: deltaX=" + String.valueOf(e2.getX() - e1.getX()) + ", deltaY=" + String.valueOf(e2.getY() - e1.getY()));
            return true;
        }

        @Override
        public boolean onSingleTapUp(MotionEvent e)
        {
            Log.e("", "onSingleTapUp: X=" + String.valueOf(e.getX()) + ", Y=" + String.valueOf(e.getY()));
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e)
        {
            Log.e("", "onLongPress: X=" + String.valueOf(e.getX()) + ", Y=" + String.valueOf(e.getY()));
        }
    }

Что бы я ни делал с сенсорным экраном, я получаю только onLongPress. На самом деле, когда я делаю быстрое касание (быстро касаясь экрана и отпуская его), я все еще получаю немного onLongPress после того, как убираю палец с экрана (подозреваю, что это длинная задержка обнаружения касания).

В чем подвох?


person Violet Giraffe    schedule 01.11.2013    source источник
comment
вы пытались изменить return super.onTouchEvent(event); на return false;? И попробуйте свои действия в простом представлении (например, в WebView).   -  person    schedule 01.11.2013
comment
@R.id.pandacoder: return false; ничего не меняет.   -  person Violet Giraffe    schedule 01.11.2013
comment
После некоторого исследования, я думаю, вы можете попробовать добавить метод onDown, который возвращает true, к вашему методу onTouchEvent.   -  person    schedule 01.11.2013
comment
Вы всегда будете давать onLongPress, потому что MotionEvent.ACTION_DOWN никогда не обрабатывалось\не обращалось на ваш жестДетектор. Вы всегда будете давать ACTION_UP. Почему нет ACTION_MOVE? Потому что в Android Action_Move прецессируется после того, как он дает Action_UP. Таким образом, детектор жестов будет обрабатывать ваши действия, как долгое нажатие.   -  person    schedule 01.11.2013
comment
@R.id.pandacoder: спасибо! Кажется глупым, что нет реализации по умолчанию или что onDown не является абстрактным...   -  person Violet Giraffe    schedule 01.11.2013


Ответы (1)


Я цитирую Руководство Android по обнаружению распространенных жестов:

Независимо от того, используете вы GestureDetector.OnGestureListener или нет, рекомендуется реализовать метод onDown(), который возвращает значение true. Это связано с тем, что все жесты начинаются с сообщения onDown(). Если вы возвращаете false из onDown(), как GestureDetector.SimpleOnGestureListener делает по умолчанию, система предполагает, что вы хотите игнорировать остальную часть жеста, а другие методы GestureDetector.OnGestureListener никогда не вызываются. Это может вызвать неожиданные проблемы в вашем приложении. Единственный раз, когда вы должны вернуть false из onDown(), это если вы действительно хотите игнорировать весь жест.

Тот факт, что вы не реализовали метод onDown(), вызывал побочные эффекты.

person iversoncru    schedule 21.03.2014
comment
Как ни странно, у меня была та же проблема, что и у OP, за исключением того, что мой метод onLongPress вызывался просто отлично, несмотря на то, что onDown не возвращал true - person AgentKnopf; 09.05.2015