Invalid onInterceptTouchEvent pointer count

I want my ViewPager to be just a slide when using one finger. So I extended the class and implemented onInterceptTouchEvent as follows:

@Override public boolean onInterceptTouchEvent(MotionEvent ev) { if(ev.getPointerCount() > 1) { return false; } return true; } 

But getPointerCount () always returns "1", no matter how many points there are on the screen. I get the correct number when I redefine onTouchEvent, but when I do this, the error prevents the pager from working at all ( http://code.google.com/p/android/issues/detail?id=18990 ) when you pulled your first finger from multitouch: java.lang.IllegalArgumentException: pointerIndex out of range

How else can I do this?

EDIT:

The pointer counter error remains, but I managed to bypass the exception that gets into onTouchEvent.

I did this when I got the exception:

 if(ev.getPointerCount() == 1) { return super.onTouchEvent(ev); } return false; 

The problem is that when the first finger is pulled out of the multitouch, ViewPager onTouchEvent terminates the processing of the ACTION_UP event without first processing ACTION_DOWN. So I came up with this fix that avoids the exception and stops the ViewPager moving when you put your second finger:

 private boolean moving = false; @Override public boolean onTouchEvent (MotionEvent ev) { int action = ev.getAction(); if(action == MotionEvent.ACTION_DOWN) { moving = true; } if(ev.getPointerCount() == 1) { if(moving) { return super.onTouchEvent(ev); } if(action == MotionEvent.ACTION_UP) { moving = false; } } else if(ev.getPointerCount() > 1 && moving) { ev.setAction(MotionEvent.ACTION_UP); moving = false; return super.onTouchEvent(ev); } return false; } 
+4
source share
2 answers

Your onTouchEvent did not work for me. I will investigate why. But meanwhile, I made another way around the problem. I burst into ViewPager code and found that you can do this:

 @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (ev.getPointerCount() > 1){ ev.setAction(MotionEvent.ACTION_CANCEL); } return super.onInterceptTouchEvent(ev); } 

getPointerCount () works fine for me. Using the above code, the ViewPager also processes the ACTION_DOWN step, and an error never occurs in it.

+4
source

So, I finally figured out how to solve the same problem and understand why this happens in the first place. I solved the problem without the ViewPager extension, but instead just installed touch events on the listener, as in the example:

 viewPager.setOnTouchListener(new OnTouchListener() { // TODO This breaks sometimes in compatibility library code, try to fix @Override public boolean onTouch(View v, MotionEvent event) { currentFragment.view.dispatchTouchEvent(event); if (!currentFragment.view.whole && event.getPointerCount() > 1) { event.setAction(MotionEvent.ACTION_CANCEL); } return false; } }); 

So, you just need to set the event as canceled, and not use it. When you return true in the onTouch method event, it is consumed and does not go to the view pager, so it stops scrolling. But when you process several events of the pointer, it disables the event after the second touch, but it is still dispatched first, therefore the view handler and the touch handler try to act upon repeated touch and breaks because the second event element for the second finger is missing.

I agree that this should not happen, and this is a bug in the support library reported here (I think it is) https://code.google.com/p/android/issues/detail?id=18990 This was noted as resolved some time ago, but is still happening in the newest version of SupportLibrary V4

0
source

All Articles