Proper scroll detection in GridView hosted inside ViewPager in Android

I have a ViewPager that uses GridViews for pages. I would like ViewPager to switch pages as I scroll through the screen.

The problem is that swipes are not detected when they are done through the GridView. Outside of the GridView, palms are working correctly; it seems that the GridView captures all touch events without passing it to the ViewPager first.

While working with the source code, I did this for a special class extended from GridView:

@Override public boolean onTouchEvent(MotionEvent event) { return pager.onInterceptTouchEvent(event); } 

- where pager belongs to the ViewPager class. In this case, the ViewPager will correctly detect errors and move pages accordingly, but this does not allow the GridView to receive any events, so I can not click on the elements.

What I would like to do is correctly detect the swipes in the ViewPager and click the element on the GridView.

+6
source share
3 answers

I had problems executing colig, but I was able to get it working by subclassing the ViewPager and overriding the onInterceptTouchEvent () method. I checked only scrolling in the X direction, so that, if necessary, to perform vertical scrolling.

 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; } 
+6
source

Alix is ​​on the right track. I managed to come up with this simple solution. I'm not quite sure how this works, but it is! And for future use, it works for other types of views - TableLayout, for example - not only 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); } 
+2
source

You can override onInterceptTouchEvent to align send where you want

+1
source

Source: https://habr.com/ru/post/911498/


All Articles