ScrollView внутри галереи, прокручивая независимо

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

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

Без переопределения каких-либо методов просмотр прокрутки – это единственное, что прокручивается – галерея никогда не прокручивает.

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

Solutions Collecting From Web of "ScrollView внутри галереи, прокручивая независимо"

Хорошо, после некоторого серьезного взлома и взлома лоцката, вот решение:

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); } } } } 

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