I have a ViewPager which uses GridViews for pages. I would like the ViewPager to switch pages when I swipe across the screen.
The problem is that swipes are not detected when they are made across the GridView. Outside of the GridView, the swipes work correctly; it seems that the GridView is trapping all touch events without passing it to ViewPager first.
While fiddling with the source code, I did this to a custom class extended from GridView:
@Override
public boolean onTouchEvent(MotionEvent event) {
return pager.onInterceptTouchEvent(event);
}
-- where pager
refers to the ViewPager class. With this, ViewPager will correctly detect swipes and move pages accordingly, but it doesn't allow GridView to accept any events, so I can't click on the items.
What I would like to be able to do is correctly detect swipes in ViewPager and item clicks on GridView.
I had trouble with colig's implementation, but I was able to get it to work by subclassing ViewPager and overriding the onInterceptTouchEvent() method. I only checked for swipes in the X direction to allow for vertical scrolling if necessary.
private static final int minSwipeDistance = 30;
private float mTouchX;
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean response = super.onInterceptTouchEvent(event);
float x = event.getX();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mTouchX = x;
break;
case MotionEvent.ACTION_MOVE:
float dX = Math.abs(x - mTouchX);
if (dX > minSwipeDistance)
return true;
break;
}
return response;
}
Alix is on the right track. I managed to come up with this simple-looking fix. I'm not entirely sure of how it works, but it does! And for future reference, it works for other kinds of views too -- TableLayout, for example -- not just GridView.
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
x = event.getX();
y = event.getY();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
downX = x;
downY = y;
return super.onInterceptTouchEvent(event);
}
case MotionEvent.ACTION_MOVE: {
deltaX = Math.abs(downX - x);
deltaY = Math.abs(downY - y);
return super.onTouchEvent(event);
}
case MotionEvent.ACTION_UP: {
if (deltaX > 4 && deltaY > 4) {
super.onTouchEvent(event);
}
}
}
return super.onInterceptTouchEvent(event);
}
You can override onInterceptTouchEvent for dispatch evenement where you want
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With