在4.0上使用onTouchListener和onClickListener的Android TextView NullPointerException

我有一个TextView,我已经分配了onTouchListener和onClickListener:

myTextView.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { _gestureDetector.onTouchEvent(event); return false; } }); myTextView.setOnClickListener(new OnClickListener() { public void onClick(View v) { // Show Toast Notification } }); 

onTouchListener将检测手势检测器的onFling()。 这个代码没有任何问题,除了Android 4.0(冰淇淋三明治)。 使用4.0,我在“_gestureDetector.onTouchEvent(event);”上收到NullPointerException。 (当我试图逃跑时)。

但是,如果我注释掉onClickListener,则fling将起作用,我将不会收到NullPointerException。

我假设如果触摸侦听器都返回false,则不会消耗该事件,从而允许两者都工作。

有没有人有任何想法? 谢谢!

这是我的更多代码:

  /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.calendar); _gestureDetector = new GestureDetector(new GestureListener()); } private class GestureListener extends SimpleOnGestureListener { @Override public boolean onDown(MotionEvent e) { return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) { // Bottom to top _calendarTableLayout.removeAllViews(); int month = _calendar.get(Calendar.MONTH); _calendar.set(Calendar.MONTH, month + 1); _calendar.set(Calendar.DATE, 1); // important drawCalendar(); return true; } else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) { // Top to bottom _calendarTableLayout.removeAllViews(); int month = _calendar.get(Calendar.MONTH); _calendar.set(Calendar.MONTH, month - 1); _calendar.set(Calendar.DATE, 1); // important redrawCalendar(); return true; } return false; } @Override public void onLongPress(MotionEvent e) { // Do nothing } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // Do nothing return false; } @Override public void onShowPress(MotionEvent e) { // Do nothing } @Override public boolean onSingleTapUp(MotionEvent e) { // Do nothing return false; } } 

堆栈跟踪:

  01-27 11:12:16.406: E/AndroidRuntime(1448): FATAL EXCEPTION: main 01-27 11:12:16.406: E/AndroidRuntime(1448): java.lang.NullPointerException 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.GestureDetector.onTouchEvent(GestureDetector.java:587) 01-27 11:12:16.406: E/AndroidRuntime(1448): at com.my.package.MyActivity$9.onTouch(MyActivity.java:287) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.View.dispatchTouchEvent(View.java:5481) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1959) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1728) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1959) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1728) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1959) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1728) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1959) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1728) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1959) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1728) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1959) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1728) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1959) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1728) 01-27 11:12:16.406: E/AndroidRuntime(1448): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1892) 01-27 11:12:16.406: E/AndroidRuntime(1448): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1371) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.app.Activity.dispatchTouchEvent(Activity.java:2364) 01-27 11:12:16.406: E/AndroidRuntime(1448): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java: 1840) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.View.dispatchPointerEvent(View.java:5662) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2863) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.os.Handler.dispatchMessage(Handler.java:99) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.os.Looper.loop(Looper.java:137) 01-27 11:12:16.406: E/AndroidRuntime(1448): at android.app.ActivityThread.main(ActivityThread.java:4340) 01-27 11:12:16.406: E/AndroidRuntime(1448): at java.lang.reflect.Method.invokeNative(Native Method) 01-27 11:12:16.406: E/AndroidRuntime(1448): at java.lang.reflect.Method.invoke(Method.java:511) 01-27 11:12:16.406: E/AndroidRuntime(1448): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 01-27 11:12:16.406: E/AndroidRuntime(1448): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 01-27 11:12:16.406: E/AndroidRuntime(1448): at dalvik.system.NativeStart.main(Native Method) 

我的朋友,当你从_gestureDetector获得你想要处理的事件时,尝试返回true:

  public boolean onTouch(View v, MotionEvent event) { if (_gestureDetector.onTouchEvent(event)) { return true; } return false; } 

否则,返回false。

我看了一下GestureDetector的Android源代码(4.0.1 r1): http ://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android /view/GestureDetector.java?av=f

第587行似乎不是问题的根源,因为mVelocityTracker总是被该点初始化。 你知道你有4.0的哪个版本?

这可能是4.0中的一个错误,我会在这里向他们提交一个错误报告:

http://code.google.com/p/android/issues/list

同时,您是否可以将OnClickListener中的代码移动到SimpleGestureListener的OnSingleTapConfirmed方法中? 这样,它应该仍然做正确的事情,就像你的点击监听器被注释掉,但你得到相同的行为。

http://developer.android.com/reference/android/view/GestureDetector.SimpleOnGestureListener.html#onSingleTapConfirmed(android.view.MotionEvent)