Иногда GestureDetector пропускает на Fling

У меня есть приложение, которое использует GestureDetector, и я заменяю некоторые изображения onDown и onFling (он же onUp). Однако в некоторых случаях onFling не вызывается, и результат не очень приятный:)

Сталкивались ли вы с такой проблемой и нашли ли вы исправление / обходной путь (помимо использования тайм-аута)?
Вот небольшой код:

    final GestureDetector gdt1 = new GestureDetector(getApplicationContext(), new MyGestureDetector(mGestDetector, R.id.weatherFrame1));
    FrameLayout weatherFrame1 = (FrameLayout)findViewById(R.id.weatherFrame1);
    if (weatherFrame1 != null)
    {
        weatherFrame1.setOnTouchListener(new View.OnTouchListener()
        {
            @Override
            public boolean onTouch(final View view, final MotionEvent event)
            {
                gdt1.onTouchEvent(event);
                return true;
            }
        });
    }

И вот часть MyGestureDetector.java

    public class MyGestureDetector implements GestureDetector.OnGestureListener{
    {
    ...
        @Override
        public boolean onDown(MotionEvent e)
        {
            int index = e.getActionIndex();
            int pointerId = e.getPointerId(index);

            if (startingPointerId == -1)
            {
                Log.i("MyGestureDetector", "Pointer is " + pointerId);

                if (pointerId == 0)
                {
                    startingPosX = e.getX(pointerId);
                    startingPosY = e.getY(pointerId);
                    startingPointerId = pointerId;
                    if (null != mGestureListener)
                    {
                        mGestureListener.onDown(mGestureOrigin);
                    }
                }
            }
            return true;
        }
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
        {
            startingPointerId = -1;
            if (null != mGestureListener)
            {
                mGestureListener.onUp(mGestureOrigin);
            }
            return true;
        }
    }

1 ответ

Решение

Для обнаружения событий "вверх" и "вниз" я бы порекомендовал что-то простое:

@Override
public boolean onTouch(final View view, final MotionEvent event) {

   if (event.getAction() == MotionEvent.ACTION_UP) {
      // handle up event
   } else if (event.getAction() == MotionEvent.ACTION_DOWN) {
      // handle down event
   }

}

Изменить: наиболее вероятная причина onFling не вызывается каждый раз, потому что это не просто способ обработки событий UP. Глядя на исходный код Android, onFling вызывается только тогда, когда скорость достигает минимальной скорости, которую необходимо считать "броском". Проверьте это:

 case MotionEvent.ACTION_UP:
        mStillDown = false;
        MotionEvent currentUpEvent = MotionEvent.obtain(ev);
        if (mIsDoubleTapping) {
            // Finally, give the up event of the double-tap
            handled |= mDoubleTapListener.onDoubleTapEvent(ev);
        } else if (mInLongPress) {
            mHandler.removeMessages(TAP);
            mInLongPress = false;
        } else if (mAlwaysInTapRegion) {
            handled = mListener.onSingleTapUp(ev);
        } else {

            // A fling must travel the minimum tap distance
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
            final float velocityY = velocityTracker.getYVelocity();
            final float velocityX = velocityTracker.getXVelocity();

            if ((Math.abs(velocityY) > mMinimumFlingVelocity)
                    || (Math.abs(velocityX) > mMinimumFlingVelocity)){
                handled = mListener.onFling(mCurrentDownEvent, ev, velocityX, velocityY);
            }
        }

Наиболее заметно:

 if ((Math.abs(velocityY) > mMinimumFlingVelocity)
          || (Math.abs(velocityX) > mMinimumFlingVelocity)){
      handled = mListener.onFling(mCurrentDownEvent, ev, velocityX, velocityY);
 }

(Источник: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/view/GestureDetector.java)

Другие вопросы по тегам