Android 手势检测器不';无法使用可滚动列表活动

Android 手势检测器不';无法使用可滚动列表活动,android,gesture-recognition,Android,Gesture Recognition,我有一个带有两个视图的简单应用程序,一个是TableView,另一个是ListView。我使用GestureDetector来检测屏幕上的滑动,与此类似。如果列表视图中只填充了几个项目,则一切正常,但是当列表视图填满整个屏幕时,手势检测停止工作。在屏幕上滑动只会突出显示列表项之一 我认为这是因为ListView以某种方式从GestureListener窃取了触摸事件。有什么方法可以防止这种情况发生吗?您可以创建一个自定义的listview,然后在其内部,即在列表的每一行上实现手势检测器。可能值得

我有一个带有两个视图的简单应用程序,一个是TableView,另一个是ListView。我使用GestureDetector来检测屏幕上的滑动,与此类似。如果列表视图中只填充了几个项目,则一切正常,但是当列表视图填满整个屏幕时,手势检测停止工作。在屏幕上滑动只会突出显示列表项之一


我认为这是因为ListView以某种方式从GestureListener窃取了触摸事件。有什么方法可以防止这种情况发生吗?

您可以创建一个自定义的listview,然后在其内部,即在列表的每一行上实现手势检测器。可能值得一试。

我发现,如果您遍历一条相当精确的水平路径,那么GestureDetector在ListItems中工作得很好。但是,如果您稍有偏离,列表会滚动,手势不会完成。目前的情况如下:

  • GestureDetector首先通过setOnTouchListener()从您在ListItems中安装的onTouch获取运动事件
  • 同时,ListView正在侦听通过onInterceptTouchEvent()发送到其子视图的事件
  • ListView检测到您已开始滚动,并从onInterceptTouchEvent()返回true
  • 从那时起,MotionEvents将发送到ListView,而不是原始目标。。。ListView开始在其onTouch处理程序中接收MotionEvents。这将一直持续到最后行动结束。(请注意,从ACTION_DOWN到ACTION_MOVEs再到ACTION_UP的MotionEvents都被视为一个手势,在序列中的最后一个ACTION_UP之后,一切都会重新开始)
  • 原始目标(ListItem)获得一个ACTION\u CANCEL MotionEvent,ListItem中的GestureDetector退出。如果您将GestureDetector的代码粘贴到应用程序中并逐步执行,则可以看到这种情况
我需要我的应用程序表现得像水平滑动一样,即使触摸稍微偏离水平方向

解决方案: 这涉及ViewGroup.requestDisallowernCepttouchevent(布尔DisallowernCept),它使父级无法窥视运动事件。该方法包括实现onTouchListener来检测轻微的滑动(10像素左右),然后停止父级截取运动事件。然后,家长将不会滚动,手势检测器将继续完成

代码如下:

private boolean mFlingInProgress = false;
private float mStartX = 0;
private final int FLING_TRIGGER_DISTANCE = 10;

@Override
public boolean onTouch(View v, MotionEvent event) {
    int action = event.getAction();
    float currentX = event.getRawX();

    switch (action) {
    case MotionEvent.ACTION_DOWN:
        mStartX = currentX;
        break;
    case MotionEvent.ACTION_MOVE:
        if (false == mFlingInProgress) {
            if (Math.abs(currentX - mStartX) > FLING_TRIGGER_DISTANCE) {
                // stop the parent intercepting motion events
                mLayout.getParent().requestDisallowInterceptTouchEvent(true);
                mFlingInProgress = true;
            }
        } 
        break;
    case MotionEvent.ACTION_UP:
        mFlingInProgress = false;
        break;
    }

    return mGestureDetector.onTouchEvent(event);
}

我想了想,但想找更干净的。