6

我有一个带有适配器的画廊,该适配器为其提供 ScrollViews 作为其子视图。我需要确保按预期正确处理触摸事件:

  1. 当用户水平滚动时,图库会水平滚动。
  2. 当用户垂直滚动时,滚动视图会垂直滚动。
  3. 两个滚动都不应该发生在同一个手势上(用户必须抬起手指才能滚动另一个视图)。
  4. 一切都必须流畅滚动。

在不覆盖任何方法的情况下,滚动视图是唯一滚动的东西——图库从不滚动。

所以我知道我需要在图库中使用 onInterceptTouchEvent(...) 来决定接管某个系列的 MotionEvent,但我不确定如何检查触摸本质上是水平的还是垂直的。

4

2 回答 2

19

好的,经过一些重大的摆弄和 logcat 黑客攻击,这里是解决方案:

public class SwipeInterceptingGallery extends Gallery {

    private float mInitialX;
    private float mInitialY;
    private boolean mNeedToRebase;
    private boolean mIgnore;

    public SwipeInterceptingGallery(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public SwipeInterceptingGallery(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SwipeInterceptingGallery(Context context) {
        super(context);
    }

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                mIgnore = false;
                mNeedToRebase = true;
                mInitialX = e.getX();
                mInitialY = e.getY();
                return false;
            }

            case MotionEvent.ACTION_MOVE: {
                if (!mIgnore) {
                    float deltaX = Math.abs(e.getX() - mInitialX);
                    float deltaY = Math.abs(e.getY() - mInitialY);
                    mIgnore = deltaX < deltaY;
                    return !mIgnore;
                }
                return false;
            }
            default: {
                return super.onInterceptTouchEvent(e);
            }
        }
    }
}
于 2011-03-13T12:02:15.307 回答
0

我已经尝试过Warlax提供的解决方案。它让我前进,但不幸的是,它在极少数情况下会破坏正常的画廊行为。(例如它在滚动时不会停止触摸)所以我做了更多的研究并提出了以下解决方案。

public class TouchInterceptingGallery extends Gallery {

    public TouchInterceptingGallery(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public TouchInterceptingGallery(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TouchInterceptingGallery(Context context) {
        super(context);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        this.onTouchEvent(ev);
        return false;
    }

}
于 2011-09-07T08:01:14.050 回答