3

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

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

  1. 检测子视图上的多点触控事件
  2. 然后将触摸控制传递给父母

但是在将侦听器事件从子视图传递到父视图时,它会给出以下错误:

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)

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

分析:这里我检查了使用FrameLayout而不是Child Fragment中的Listview。并且它没有任何提到的问题..但不适用于 ListView。

设备信息: OS V4.4.4 S5。

任何建议!

4

1 回答 1

-1

I don't know why MotionEventCompat is calling MotionEventCompatEclair, as I saw in the code, there are a MotionEventCompatHoneycomb overload, but I had the same problem with Moto XT1040 in android 4.4.4.

The solution for me was create my version of ViewPager(I just copied the entire class from android source) and in the method onInterceptTouchEvent(MotionEvent ev) in the case of MotionEvent.ACTION_MOVE change the initial lines from:

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

to:

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 = ev.getX(pointerIndex);
final float dx = x - mLastMotionX;
final float xDiff = Math.abs(dx);
final float y = ev.getY(pointerIndex);
final float yDiff = Math.abs(y - mInitialMotionY);

The only change was in the x and y variables, I changed to call the MotionEvent getX and getY method directly, ignoring the MotionEventCompat.

My app was minimum api 14, if you are supporting something previous from 14, I suggest to you call the closest MotionEventCompat from your version. You just need to prevent from calling the MotivoEventCompatEclair version.

于 2015-07-16T16:39:46.803 回答