Android InterceptTouchEvent上的指针计数不正确

Android InterceptTouchEvent上的指针计数不正确,android,android-viewpager,Android,Android Viewpager,我希望我的ViewPager仅在使用单手指时滑动。因此,我扩展了该类并实现了onInterceptTouchEvent,如下所示: @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if(ev.getPointerCount() > 1) { return false; } return true; } 但是getPointerCount()总是返回“1”,不管

我希望我的ViewPager仅在使用单手指时滑动。因此,我扩展了该类并实现了onInterceptTouchEvent,如下所示:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
    if(ev.getPointerCount() > 1)
    {
        return false;
    }
    return true;
}
但是getPointerCount()总是返回“1”,不管屏幕上有多少个点。当我重写onTouchEvent时,我得到了正确的数字,但是当我这样做时,一个bug正在阻止寻呼机工作(),因为当你将第一个手指从multitouch中伸出时,会抛出一个应用程序终止异常:java.lang.IllegalArgumentException:pointerIndex超出范围

我还能怎么做呢

编辑:

指针计数问题仍然存在,但我能够解决onTouchEvent中抛出的异常

当我遇到异常时,我正在这样做:

if(ev.getPointerCount() == 1)
{
    return super.onTouchEvent(ev);
}
return false;
问题在于,当您将第一个手指伸出多点触摸时,ViewPager的onTouchEvent最终会处理ACTION_up事件,而不会首先处理ACTION_DOWN。因此,我提出了这个解决方案,它避免了异常,并将在您放下第二个手指时结束ViewPager的移动:

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;
}

你的电话对我不起作用。我会调查原因。但与此同时,我做了另一个变通办法。我深入研究了ViewPager代码,发现您可以这样做:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {

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

    return super.onInterceptTouchEvent(ev);

}

getPointerCount()对我来说还可以。通过上面的代码,ViewPager也处理了操作步骤,其中的错误从未发生过。

因此,我终于找到了解决相同问题的方法,并初步了解了为什么会发生这种情况。我在没有扩展ViewPager的情况下解决了这个问题,而是设置了触摸事件侦听器,如示例所示:

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;
        }
    });
所以你要做的就是将事件设置为已取消,而不是使用它。当您在onTouch方法中返回true时,事件将被消耗,并且不会向视图页面冒泡,因此它将停止滚动。但当您处理多个指针事件时,它会在第二次触摸后剪切事件,但第一次仍会发送,因此viewpager和touch处理程序会尝试对多个触摸进行操作,并会中断,因为finger two没有事件的第二个元素

我同意这种情况不应该发生,这是这里报告的支持库中的一个bug(我认为就是这个bug)
它在一段时间前被标记为已解决,但在最新版本的SupportLibrary V4中仍会出现

非常好的解决方案,谢谢!这真的为我节省了很多工作,我想我已经尝试了所有的方法,包括下面的答案,这仍然会导致异常。这最终解决了我遇到的类似问题,但不幸的是,我不得不艰难地找到它,因为搜索没有找到你的答案。我会在下面的答案中多写一点。