简体   繁体   中英

Android TextView NullPointerException with onTouchListener and onClickListener on 4.0

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.

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

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM