5

我希望我的 ViewPager 仅在使用单指时滑动。所以我扩展了这个类并像这样实现了 onInterceptTouchEvent:

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

但无论屏幕上有多少点,getPointerCount() 总是返回“1”。当我覆盖 onTouchEvent 时,我得到了正确的数字,但是当我这样做时,一个错误会通过抛出来阻止寻呼机工作(http://code.google.com/p/android/issues/detail?id=18990)当您将第一根手指从多点触控中抬起时出现应用程序终止异常:java.lang.IllegalArgumentException:pointerIndex out of range

我还能怎么做呢?

编辑:

指针计数问题仍然存在,但我能够解决 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;
}
4

2 回答 2

5

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

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {

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

    return super.onInterceptTouchEvent(ev);

}

getPointerCount() 不过对我来说没问题。使用上面的代码 ViewPager 也处理 ACTION_DOWN 步骤并且其中的错误永远不会发生。

于 2013-01-24T05:57:45.833 回答
0

所以我终于找到了如何解决同样的问题,并且知道它为什么会发生。我在没有扩展 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 和触摸处理程序会尝试对多点触摸进行操作并中断,因为没有第二个手指事件的第二个元素。

我同意这不应该发生,这是这里报告的支持库中的一个错误(我认为是那个) https://code.google.com/p/android/issues/detail?id=18990 它被标记前段时间已解决,但仍在最新版本的 SupportLibrary V4 中发生

于 2013-07-12T09:50:27.693 回答