Подтвердить что ты не робот

Android SimpleOnGestureListener.onFling получает нулевой MotionEvent

Я пытаюсь обнаружить событие fling в простом приложении для Android, но первый аргумент MotionEvent всегда равен нулю. Почему метод onFling вызывается с нулевым аргументом? Документация Android говорит, что она вызывается, когда происходит событие fling с начальным нажатием MotionEvent и соответствующим MotionEvent.

class MyGestureDetector extends SimpleOnGestureListener {
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        // e1 always == null, return early a null reference exception
        if (e1 == null) {
            return false;
        }
        if (e1.getY() - e2.getY() > 120) {
            handleFlingEvent();
            return true;
        }
        return false;
    }
}

Основная операция имеет этот метод onTouchEvent:

GestureDetector flingDetector = new GestureDetector(new MyGestureDetector());

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (flingDetector.onTouchEvent(event)) {
        return true;
    }
    return super.onTouchEvent(event);
}
4b9b3361

Ответ 1

У меня есть аналогичная проблема. Это происходит, когда GestureDetector и метод onFling находятся в пользовательском классе представления, который является частью пользовательского интерфейса активности. После серии тестов я обнаружил, что только основная активность может хорошо распознать жестом салфетки. Поэтому я решу проблему, заменяя их в своей деятельности. Но я не нашел основной причины этой проблемы.

Ответ 2

Я впервые столкнулся с этой проблемой с Android 4.0, так как мой код отлично работает во всех предыдущих версиях. После взятия подсказки из предложений здесь я нашел легкое обходное решение - просто следить за событием onDown и использовать его вместо первого параметра onFling, если он окажется нулевым.

public class MySimpleGestureListener extends SimpleOnGestureListener {
    protected MotionEvent mLastOnDownEvent = null;

    @Override
    public boolean onDown(MotionEvent e) {
        mLastOnDownEvent = e;
        return true;//super.onDown(e);
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if (e1==null)
            e1 = mLastOnDownEvent;
        if (e1==null || e2==null)
            return false;
        float dX = e2.getX()-e1.getX();
        float dY = e2.getY()-e1.getY();
        ...rest of code
    }

    ...rest of class
}

Ответ 3

У меня такая же проблема с пользовательским представлением и OnGestureListener onFling. Обнаружили это:

Независимо от того, используете ли вы GestureDetector.SimpleOnGestureListener, вы должен всегда реализовывать метод onDown(), который возвращает true.

Получено из http://developer.android.com/training/custom-views/making-interactive.html

Ответ 4

В пользовательском классе группы просмотра вам нужно переопределить 2 метода: onInterceptTouchEvent и onTouchEvent. После этого вам нужно вызвать GestureDetector.onTouchEvent() в обоих методах. Событие ACTION_DOWN передается только onInterceptTouchEvent.

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

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

Ответ 5

У меня было 3 кнопки в горизонтальной линейной компоновке, и этот макет, в свою очередь, был окружен horizontalscrollview.

Затем я установил simplegesturelistener на horizontalscrollview и получил ту же ошибку, что и выше. Затем я также установил simplegesturelistener для всех кнопок в макете и работал.

Ответ 6

Я думаю, что событие onDown было возобновлено scrollview, поэтому мы не можем получить событие в активности. Если вы настроите ScrollView и переопределите dispatchTouchEvent() и onTouchEvent(), проблема будет решена.

Активность:

public class TestActivity extends Activity {
     private MyScrollView scrollView;
     private TestActivity me;
     private GestureDetector detector; 

     protected void onCreate(Bundle savedInstanceState) {
            this.me = this;
            MySimpleGestureListener gestureListener = new MySimpleGestureListener();
            this.detector = new GestureDetector(gestureListener);
            this.scrollView.setOnTouchListener(onTouchListerner);
            this.scrollView.setDetector(detector);
     }

     private View.OnTouchListener onTouchListener = new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return me.detector.onTouchEvent(event);
    }
 };
}

MySimpleGestureListener:

public class MySimpleGestureListener extends SimpleOnGestureListener {
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
            float distanceY) {
        return super.onScroll(e1, e2, distanceX, distanceY);
    }

    @Override
    public void onLongPress(MotionEvent e) {
    }


    @Override
    public boolean onDown(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY) {
                    // TODO do your onFling here

    }
}

Наконец, MyScrollView

public class MyScrollView extends ScrollView {
    private GestureDetector detector;

    @Override
public boolean dispatchTouchEvent(MotionEvent ev){
    if (this.detector!= null) {
            detector.onTouchEvent(ev);
        super.dispatchTouchEvent(ev);
        return true;
    }
    return super.dispatchTouchEvent(ev);
} 

@Override
public boolean onTouchEvent(MotionEvent ev) {
    super.onTouchEvent(ev);
    //
    if (this.detector != null) {
        return this.detector.onTouchEvent(ev);
    } 
    return false;
}

    // here is the getter and setter
}

Надеюсь на эту помощь.