android - 手势检测器不适用于可滚动列表 Activity

标签 android gesture-recognition

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

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

最佳答案

我发现,如果您遍历相当准确的水平路径,GestureDetector 在 ListItems 中工作得很好。但是,如果您稍微偏离,列表就会滚动并且手势不会完成。事情的经过如下:

  • GestureDetector 首先愉快地从您通过 setOnTouchListener() 安装在 ListItems 中的 onTouch 获取 MotionEvents。
  • ListView 同时监听通过 onInterceptTouchEvent() 发送到其 subview 的事件
  • ListView 检测到您已开始滚动并从 onInterceptTouchEvent() 返回 true。
  • 从那时起,MotionEvents 将被发送到 ListView 而不是原始目标...ListView 开始在其 onTouch 处理程序中接收 MotionEvents。这一直持续到最后的 ACTION_UP。 (请注意,从 ACTION_DOWN 到所有 ACTION_MOVE 到 ACTION_UP 的 MotionEvent 被视为单个手势,并且在序列中的最后一个 ACTION_UP 之后一切都会重新开始)
  • 原始目标 (ListItem) 收到 ACTION_CANCEL MotionEvent,并且 ListItem 中的 GestureDetector 退出。如果您将 GestureDetector 的代码粘贴到您的应用程序中并单步执行,就会看到这种情况发生。

我需要我的应用程序表现得就像水平滑动继续,即使触摸稍微偏离水平方向。

解决方案: 这涉及 ViewGroup.requestDisallowInterceptTouchEvent (boolean disallowIntercept),它阻止父级查看运动事件。该方法涉及实现 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);
}

关于android - 手势检测器不适用于可滚动列表 Activity ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4446678/

相关文章:

android - 具有大型原始文本文件的应用程序无法在 Android 手机上运行

android - 找不到 build.xml (Android)

theory - Kinect手势识别理论

iphone - 如何在iPhone上进行捏合手势?

iphone - 如何为 UITextView 启用滑动手势

delphi - Delphi 中手势识别的性能影响?

android - 滚动到顶部将 ListView 项目移动到第二个位置

java - Objective-C 到 Java 交叉编译器

java - 获取艺术家的唱片目录,就像 musicbrainz 上的概览页面一样

android - 抽屉中的 SwipeRefreshLayout 手势检测