手势检测器不适用于可滚动列表活动

时间:2010-12-15 04:25:52

标签: android gesture-recognition

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

我认为这种情况正在发生,因为ListView以某种方式窃取了GestureListener的触摸事件。有办法防止这种情况吗?

2 个答案:

答案 0 :(得分:2)

如果你遍历一个相当准确的水平路径,我发现GestureDetector在ListItems中运行良好。但是,如果您稍微偏离,则列表会滚动并且手势无法完成。发生的事情如下:

  • GestureDetector很高兴从您通过setOnTouchListener()安装在ListItems中的onTouch中开始使用MotionEvents。
  • ListView同时通过onInterceptTouchEvent()
  • 监听发送到其子视图的事件
  • ListView检测到您已开始滚动并从onInterceptTouchEvent()返回true。
  • 从那时起,MotionEvents被发送到ListView而不是原始目标...... ListView开始在其onTouch处理程序中接收MotionEvents。这一直持续到最后的ACTION_UP。 (注意,从ACTION_DOWN到ACTION_MOVEs到ACTION_UP的MotionEvents被认为是单个手势,并且在序列中的最后一个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);
}

答案 1 :(得分:1)

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