6

子ビューとしてScrollViewsを提供するアダプターを備えたギャラリーがあります。タッチイベントが正しく、期待どおりに処理されることを確認する必要があります。

  1. ユーザーが水平方向にスクロールすると、ギャラリーは水平方向にスクロールします。
  2. ユーザーが垂直方向にスクロールすると、スクロールビューが垂直方向にスクロールします。
  3. 両方のスクロールが同じジェスチャで発生することはありません(ユーザーは、他のビューをスクロールするには指を離す必要があります)。
  4. すべてがスムーズにスクロールする必要があります。

メソッドをオーバーライドしない場合、スクロールするのはスクロールビューだけです。ギャラリーは決してスクロールしません。

したがって、ギャラリーでonInterceptTouchEvent(...)を使用して、特定の一連のMotionEventを引き継ぐことを決定する必要があることは理解していますが、タッチが本質的に水平か垂直かを確認する方法がわかりません。

4

2 に答える 2

19

OK、いくつかの主要ないじりと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 に答える