I have a TextView which I've assigned both an onTouchListener and an 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
}
});
The onTouchListener will detect an onFling() for the gesture detector. This code works without any problems EXCEPT for Android 4.0 (Ice cream sandwich). With 4.0, I receive a NullPointerException on "_gestureDetector.onTouchEvent(event);" (when I try to fling).
If I comment out the onClickListener, however, the fling will work and I will not receive a NullPointerException.
I was under the assumption that if both the touch listener returned false, the event would not be consumed, allowing both to work.
Does anyone have any ideas? Thanks!
Here is more of my code:
/** 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;
}
}
Stacktrace:
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)
My friend, try to return true when you get events you want to handle from _gestureDetector:
public boolean onTouch(View v, MotionEvent event) {
if (_gestureDetector.onTouchEvent(event)) {
return true;
}
return false;
}
Otherwise, return false.
I had a look at the Android source (4.0.1 r1) for GestureDetector: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/view/GestureDetector.java?av=f
Line 587 doesn't look like it could be the source of the problem, since mVelocityTracker is always initialized by that point. Any idea which build of 4.0 you have?
This may be a bug in 4.0, and I would file a bug report to them about it here:
http://code.google.com/p/android/issues/list
In the mean time, is it possible for you do move the code in your OnClickListener into the OnSingleTapConfirmed method of the SimpleGestureListener? That way, it should still do the right thing as if your click listener is commented out, but you get the same behavior.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.