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

这是我想要实现的目标:


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


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

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索引进行了一些操作,但就我而言,我现在只是将控件传递给parent(ViewPager)视图。

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

设备信息:OS V4.4.4 S5。

有任何建议!

最佳答案

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

对我来说,解决方案是创建我的ViewPager版本(我只是从android源复制了整个类),并在MotionEvent的情况下使用onInterceptTouchEvent(MotionEvent ev)方法将初始行从以下位置更改:

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


至:

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


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

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

07-27 16:11