Да, ViewPager
и другие элементы прокрутки по умолчанию не очень хорошо сочетаются друг с другом. Когда мне приходится делать такие вещи, я обычно делаю подкласс ViewPager
, чтобы сделать что-то, что знает о детях, которые могут прокрутить. Затем в моем onInterceptTouchEvent()
я проверяю, находится ли прямоугольник попадания внутри этого потомка, и не перехватываю событие касания, чтобы у ребенка был удар по нему. Примерно так:
/**
* Override to not intercept touch events within our scroller if it exists.
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if(scrollerId != 0) {
View scroller = findViewById(scrollerId);
if(scroller != null) {
Rect rect = new Rect();
scroller.getHitRect(rect);
if(rect.contains((int)ev.getX(), (int)ev.getY())) {
return false;
}
}
}
return super.onInterceptTouchEvent(ev);
}
Тогда все, что вам нужно, - это установить scrollerId
(работает простой публичный метод).
Обратите внимание, что если вы используете ScrollView
для вертикально элементов прокрутки с ViewPager
children , вам нужно пойти в другом направлении. Имейте подкласс ScrollView
, который определяет вертикальные направления прокрутки и поручительств для горизонтальной прокрутки, поэтому ViewPager
поднимает его.
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
xDistance = yDistance = 0f;
lastX = ev.getX();
lastY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
final float curX = ev.getX();
final float curY = ev.getY();
xDistance += Math.abs(curX - lastX);
yDistance += Math.abs(curY - lastY);
lastX = curX;
lastY = curY;
if (xDistance > yDistance)
return false;
}
return super.onInterceptTouchEvent(ev);
}