Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incorrect pointer count onInterceptTouchEvent

I want my ViewPager to only slide when using a single finger. So I extended the class and implemented onInterceptTouchEvent like so:

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

But getPointerCount() is always returning '1', no matter how many points are on the screen. I get the correct number when I override onTouchEvent, but when I do that a bug is preventing the pager from working at all ( http://code.google.com/p/android/issues/detail?id=18990 ) by throwning an app-killing exception when you raised your first finger out of multitouch: java.lang.IllegalArgumentException: pointerIndex out of range

How else can I go about this?

EDIT:

The pointer count issue remains, but I was able to work around the exception that gets thrown in onTouchEvent.

I was doing this when I got the exception:

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

The problem is that that when you raise your first finger out of multitouch, the ViewPager's onTouchEvent ends up processing the ACTION_UP event without first processing ACTION_DOWN. So I came up with this fix, which avoids the exception and will end the ViewPager's move when you put down a 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;
}
like image 640
directedition Avatar asked Dec 11 '12 01:12

directedition


1 Answers

Your onTouchEvent did not work for me. I will investigate why. But meanwhile I did another workaround. I dug into ViewPager code and found that you can do that instead:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {

    if (ev.getPointerCount() > 1){
        ev.setAction(MotionEvent.ACTION_CANCEL);
    }

    return super.onInterceptTouchEvent(ev);

}

getPointerCount() works ok for me though. With the above code ViewPager processes also the ACTION_DOWN step and the bug in it never occure.

like image 200
goroncy Avatar answered Oct 11 '22 21:10

goroncy