ScrollView внутри галереи, обе прокручиваются независимо - PullRequest
6 голосов
/ 13 марта 2011

У меня есть Галерея с адаптером, который предоставляет ей ScrollViews в качестве дочерних представлений. Мне нужно убедиться, что сенсорные события обрабатываются правильно и как и ожидалось:

  1. Когда пользователь прокручивает по горизонтали, галерея прокручивает по горизонтали.
  2. Когда пользователь прокручивает по вертикали, представление прокрутки прокручивает по вертикали.
  3. Обе прокрутки никогда не должны происходить на одном и том же жесте (пользователь должен поднять палец, чтобы прокрутить другой вид).
  4. Все должно плавно прокручиваться.

Не переопределяя никакие методы, прокрутка - это единственное, что прокручивает - галерея никогда не прокручивает.

Так что я понимаю, что мне нужно использовать onInterceptTouchEvent (...) в галерее, чтобы принять решение о захвате определенной серии MotionEvents, но я не уверен, как проверить, является ли касание горизонтальным или вертикальным по своей природе.

Ответы [ 2 ]

19 голосов
/ 13 марта 2011

ОК, после некоторого взлома и взлома 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);
            }
        }
    }
}
0 голосов
/ 07 сентября 2011

Я пробовал решение, предоставленное 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;
    }

}
...