ViewPager:java.lang.IllegalArgumentException:pointerIndex超出范围

时间:2015-02-23 09:55:22

标签: android android-viewpager illegalargumentexception android-viewgroup

我正在根据建议的here编写处理触摸事件的代码。我使用ViewPager作为ViewGroup和ListView(我知道#thisbad)作为Fragment的子视图。

这就是我想要实现的目标:

  1. 检测子视图上的多点触控事件
  2. 然后将触摸控制传递给父母
  3. 但是在将侦听器事件从子视图传递到父视图时,它会出现以下错误:

    E/AndroidRuntime(11414): java.lang.IllegalArgumentException:pointerIndex out of range      
    E/AndroidRuntime(11414):    at android.view.MotionEvent.nativeGetAxisValue(Native Method)
    E/AndroidRuntime(11414):    at android.view.MotionEvent.getX(MotionEvent.java:1979)
    E/AndroidRuntime(11414):    at android.support.v4.view.MotionEventCompatEclair.getX(MotionEventCompatEclair.java:32)
    E/AndroidRuntime(11414):    at android.support.v4.view.MotionEventCompat$EclairMotionEventVersionImpl.getX(MotionEventCompat.java:91)
    E/AndroidRuntime(11414):    at android.support.v4.view.MotionEventCompat.getX(MotionEventCompat.java:219)
    E/AndroidRuntime(11414):    at android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:1971) ..................
    E/AndroidRuntime(11414):    at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:5588)
    E/AndroidRuntime(11414):    at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:5634)
    E/AndroidRuntime(11414):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
    E/AndroidRuntime(11414):    at android.view.Choreographer.doCallbacks(Choreographer.java:574)
    E/AndroidRuntime(11414):    at android.view.Choreographer.doFrame(Choreographer.java:542)
    

    我查了一些其他帖子有同样的问题likehere,但他们都使用Pointer索引来做某些事情,但在我的情况下,我现在只是将控制传递给父(ViewPager)视图。

    分析:在这里,我检查了使用FrameLayout代替Child Fragment中的Listview。它的工作没有任何提及的问题..但不是ListView。

    设备信息:OS V4.4.4 S5。

    任何建议!

1 个答案:

答案 0 :(得分:-1)

我不知道为什么MotionEventCompat正在调用MotionEventCompatEclair,正如我在代码中看到的那样,有一个MotionEventCompatHoneycomb重载,但我在android 4.4.4中遇到了与Moto XT1040相同的问题。

对我来说,解决方案是创建我的ViewPager版本(我只是从android源代码中复制了整个类),并在方法onInterceptTouchEvent(MotionEvent ev)中,在MotionEvent.ACTION_MOVE的情况下更改了初始行:

{
    "timestamp": 8374747594, 
    "owner": "text", 
    "some_more": {
        "key": "val", 
        "key": "val"
    }
}

为:

final int activePointerId = mActivePointerId;
if (activePointerId == INVALID_POINTER) {
    // If we don't have a valid id, the touch down wasn't on content.
    break;
}

final int pointerIndex = MotionEventCompat.findPointerIndex(ev, activePointerId);
final float x = MotionEventCompat.getX(ev, pointerIndex);
final float dx = x - mLastMotionX;
final float xDiff = Math.abs(dx);
final float y = MotionEventCompat.getY(ev, pointerIndex);
final float yDiff = Math.abs(y - mInitialMotionY);

唯一的变化是在x和y变量中,我改为直接调用MotionEvent getX和getY方法,忽略了MotionEventCompat。

我的应用程序是最低api 14,如果您支持14之前的某些内容,我建议您从您的版本调用最接近的MotionEventCompat。您只需要阻止调用MotivoEventCompatEclair版本。