一、问题
最近使用ViewPager + ZoomImageView实现图片预览功能时,频繁报如下异常:
# main
java.lang.IllegalArgumentException
pointerIndex out of range
1 android.view.MotionEvent.nativeGetAxisValue(Native Method)
2 android.view.MotionEvent.getX(MotionEvent.java:2014)
3 android.support.v4.view.MotionEventCompatEclair.getX(MotionEventCompatEclair.java:32)
4 android.support.v4.view.MotionEventCompat$EclairMotionEventVersionImpl.getX(MotionEventCompat.java:110)
5 android.support.v4.view.MotionEventCompat.getX(MotionEventCompat.java:462)
6 android.support.v4.view.ViewPager.onInterceptTouchEvent(ViewPager.java:1922)
7 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2000)
8 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2523)
9 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2175)
10 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2523)
11 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2175)
12 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2523)
13 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2175)
14 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2523)
15 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2175)
16 com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2559)
17 com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1815)
18 android.app.Activity.dispatchTouchEvent(Activity.java:2835)
19 com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2516)
20 android.view.View.dispatchPointerEvent(View.java:8874)
21 android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4814)
22 android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4672)
23 android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4162)
24 android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4215)
25 android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4181)
26 android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4318)
27 android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4189)
28 android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4375)
29 android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4162)
30 android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4215)
31 android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4181)
32 android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4189)
33 android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4162)
34 android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6628)
35 android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6602)
36 android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6555)
37 android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6808)
38 android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
39 android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
40 android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
41 android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6746)
42 android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6835)
43 android.view.Choreographer$CallbackRecord.run(Choreographer.java:800)
44 android.view.Choreographer.doCallbacks(Choreographer.java:603)
45 android.view.Choreographer.doFrame(Choreographer.java:570)
46 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:786)
47 android.os.Handler.handleCallback(Handler.java:815)
48 android.os.Handler.dispatchMessage(Handler.java:104)
49 android.os.Looper.loop(Looper.java:192)
50 android.app.ActivityThread.main(ActivityThread.java:5909)
51 java.lang.reflect.Method.invoke(Native Method)
52 java.lang.reflect.Method.invoke(Method.java:372)
53 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1099)
54 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:865)
二、原因
该问题的详细原因暂未找到,网上也没有具体的答案。看堆栈信息,大概就是由于在ZoomImageView中使用多点触控时,ViewPager中事件分发异常所致。
三、解决
既然该问题在ViewPager中的onInterceptTouchEvent方法中发生,在该方法中截获该异常即可;
package com.common.ui.view;
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
/**
* 修复图片在ViewPager控件中缩放报错的BUG
*/
public class ViewPagerFixed extends ViewPager {
public ViewPagerFixed(Context context) {
super(context);
}
public ViewPagerFixed(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
try {
return super.onTouchEvent(ev);
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
try {
return super.onInterceptTouchEvent(ev);
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
}
return false;
}
}