Exemple #1
0
        /// <summary>
        /// Analyzes the given motion event and if applicable triggers the
        /// appropriate callbacks on the
        /// <see cref="OnGestureListener">OnGestureListener</see>
        /// supplied.
        /// </summary>
        /// <param name="ev">The current motion event.</param>
        /// <returns>
        /// true if the
        /// <see cref="OnGestureListener">OnGestureListener</see>
        /// consumed the event,
        /// else false.
        /// </returns>
        public virtual bool onTouchEvent(android.view.MotionEvent ev)
        {
            if (mInputEventConsistencyVerifier != null)
            {
                mInputEventConsistencyVerifier.onTouchEvent(ev, 0);
            }
            int   action = ev.getAction();
            float y      = ev.getY();
            float x      = ev.getX();

            if (mVelocityTracker == null)
            {
                mVelocityTracker = android.view.VelocityTracker.obtain();
            }
            mVelocityTracker.addMovement(ev);
            bool handled = false;

            switch (action & android.view.MotionEvent.ACTION_MASK)
            {
            case android.view.MotionEvent.ACTION_POINTER_DOWN:
            {
                if (mIgnoreMultitouch)
                {
                    // Multitouch event - abort.
                    cancel();
                }
                break;
            }

            case android.view.MotionEvent.ACTION_POINTER_UP:
            {
                // Ending a multitouch gesture and going back to 1 finger
                if (mIgnoreMultitouch && ev.getPointerCount() == 2)
                {
                    int index = (((action & android.view.MotionEvent.ACTION_POINTER_INDEX_MASK) >> android.view.MotionEvent
                                  .ACTION_POINTER_INDEX_SHIFT) == 0) ? 1 : 0;
                    mLastMotionX = ev.getX(index);
                    mLastMotionY = ev.getY(index);
                    mVelocityTracker.recycle();
                    mVelocityTracker = android.view.VelocityTracker.obtain();
                }
                break;
            }

            case android.view.MotionEvent.ACTION_DOWN:
            {
                if (mDoubleTapListener != null)
                {
                    bool hadTapMessage = mHandler.hasMessages(TAP);
                    if (hadTapMessage)
                    {
                        mHandler.removeMessages(TAP);
                    }
                    if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage &&
                        isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev))
                    {
                        // This is a second tap
                        mIsDoubleTapping = true;
                        // Give a callback with the first tap of the double-tap
                        handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);
                        // Give a callback with down event of the double-tap
                        handled |= mDoubleTapListener.onDoubleTapEvent(ev);
                    }
                    else
                    {
                        // This is a first tap
                        mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);
                    }
                }
                mLastMotionX = x;
                mLastMotionY = y;
                if (mCurrentDownEvent != null)
                {
                    mCurrentDownEvent.recycle();
                }
                mCurrentDownEvent        = android.view.MotionEvent.obtain(ev);
                mAlwaysInTapRegion       = true;
                mAlwaysInBiggerTapRegion = true;
                mStillDown   = true;
                mInLongPress = false;
                if (mIsLongpressEnabled)
                {
                    mHandler.removeMessages(LONG_PRESS);
                    mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT
                                                    + LONGPRESS_TIMEOUT);
                }
                mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT
                                                );
                handled |= mListener.onDown(ev);
                break;
            }

            case android.view.MotionEvent.ACTION_MOVE:
            {
                if (mInLongPress || (mIgnoreMultitouch && ev.getPointerCount() > 1))
                {
                    break;
                }
                float scrollX = mLastMotionX - x;
                float scrollY = mLastMotionY - y;
                if (mIsDoubleTapping)
                {
                    // Give the move events of the double-tap
                    handled |= mDoubleTapListener.onDoubleTapEvent(ev);
                }
                else
                {
                    if (mAlwaysInTapRegion)
                    {
                        int deltaX   = (int)(x - mCurrentDownEvent.getX());
                        int deltaY   = (int)(y - mCurrentDownEvent.getY());
                        int distance = (deltaX * deltaX) + (deltaY * deltaY);
                        if (distance > mTouchSlopSquare)
                        {
                            handled            = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
                            mLastMotionX       = x;
                            mLastMotionY       = y;
                            mAlwaysInTapRegion = false;
                            mHandler.removeMessages(TAP);
                            mHandler.removeMessages(SHOW_PRESS);
                            mHandler.removeMessages(LONG_PRESS);
                        }
                        if (distance > mBiggerTouchSlopSquare)
                        {
                            mAlwaysInBiggerTapRegion = false;
                        }
                    }
                    else
                    {
                        if ((System.Math.Abs(scrollX) >= 1) || (System.Math.Abs(scrollY) >= 1))
                        {
                            handled      = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
                            mLastMotionX = x;
                            mLastMotionY = y;
                        }
                    }
                }
                break;
            }

            case android.view.MotionEvent.ACTION_UP:
            {
                mStillDown = false;
                android.view.MotionEvent currentUpEvent = android.view.MotionEvent.obtain(ev);
                if (mIsDoubleTapping)
                {
                    // Finally, give the up event of the double-tap
                    handled |= mDoubleTapListener.onDoubleTapEvent(ev);
                }
                else
                {
                    if (mInLongPress)
                    {
                        mHandler.removeMessages(TAP);
                        mInLongPress = false;
                    }
                    else
                    {
                        if (mAlwaysInTapRegion)
                        {
                            handled = mListener.onSingleTapUp(ev);
                        }
                        else
                        {
                            // A fling must travel the minimum tap distance
                            android.view.VelocityTracker velocityTracker = mVelocityTracker;
                            velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
                            float velocityY = velocityTracker.getYVelocity();
                            float velocityX = velocityTracker.getXVelocity();
                            if ((System.Math.Abs(velocityY) > mMinimumFlingVelocity) || (System.Math.Abs(velocityX
                                                                                                         ) > mMinimumFlingVelocity))
                            {
                                handled = mListener.onFling(mCurrentDownEvent, ev, velocityX, velocityY);
                            }
                        }
                    }
                }
                if (mPreviousUpEvent != null)
                {
                    mPreviousUpEvent.recycle();
                }
                // Hold the event we obtained above - listeners may have changed the original.
                mPreviousUpEvent = currentUpEvent;
                mVelocityTracker.recycle();
                mVelocityTracker = null;
                mIsDoubleTapping = false;
                mHandler.removeMessages(SHOW_PRESS);
                mHandler.removeMessages(LONG_PRESS);
                break;
            }

            case android.view.MotionEvent.ACTION_CANCEL:
            {
                cancel();
                break;
            }
            }
            if (!handled && mInputEventConsistencyVerifier != null)
            {
                mInputEventConsistencyVerifier.onUnhandledEvent(ev, 0);
            }
            return(handled);
        }
Exemple #2
0
		/// <summary>
		/// Analyzes the given motion event and if applicable triggers the
		/// appropriate callbacks on the
		/// <see cref="OnGestureListener">OnGestureListener</see>
		/// supplied.
		/// </summary>
		/// <param name="ev">The current motion event.</param>
		/// <returns>
		/// true if the
		/// <see cref="OnGestureListener">OnGestureListener</see>
		/// consumed the event,
		/// else false.
		/// </returns>
		public virtual bool onTouchEvent(android.view.MotionEvent ev)
		{
			if (mInputEventConsistencyVerifier != null)
			{
				mInputEventConsistencyVerifier.onTouchEvent(ev, 0);
			}
			int action = ev.getAction();
			float y = ev.getY();
			float x = ev.getX();
			if (mVelocityTracker == null)
			{
				mVelocityTracker = android.view.VelocityTracker.obtain();
			}
			mVelocityTracker.addMovement(ev);
			bool handled = false;
			switch (action & android.view.MotionEvent.ACTION_MASK)
			{
				case android.view.MotionEvent.ACTION_POINTER_DOWN:
				{
					if (mIgnoreMultitouch)
					{
						// Multitouch event - abort.
						cancel();
					}
					break;
				}

				case android.view.MotionEvent.ACTION_POINTER_UP:
				{
					// Ending a multitouch gesture and going back to 1 finger
					if (mIgnoreMultitouch && ev.getPointerCount() == 2)
					{
						int index = (((action & android.view.MotionEvent.ACTION_POINTER_INDEX_MASK) >> android.view.MotionEvent
							.ACTION_POINTER_INDEX_SHIFT) == 0) ? 1 : 0;
						mLastMotionX = ev.getX(index);
						mLastMotionY = ev.getY(index);
						mVelocityTracker.recycle();
						mVelocityTracker = android.view.VelocityTracker.obtain();
					}
					break;
				}

				case android.view.MotionEvent.ACTION_DOWN:
				{
					if (mDoubleTapListener != null)
					{
						bool hadTapMessage = mHandler.hasMessages(TAP);
						if (hadTapMessage)
						{
							mHandler.removeMessages(TAP);
						}
						if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage &&
							 isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev))
						{
							// This is a second tap
							mIsDoubleTapping = true;
							// Give a callback with the first tap of the double-tap
							handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);
							// Give a callback with down event of the double-tap
							handled |= mDoubleTapListener.onDoubleTapEvent(ev);
						}
						else
						{
							// This is a first tap
							mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);
						}
					}
					mLastMotionX = x;
					mLastMotionY = y;
					if (mCurrentDownEvent != null)
					{
						mCurrentDownEvent.recycle();
					}
					mCurrentDownEvent = android.view.MotionEvent.obtain(ev);
					mAlwaysInTapRegion = true;
					mAlwaysInBiggerTapRegion = true;
					mStillDown = true;
					mInLongPress = false;
					if (mIsLongpressEnabled)
					{
						mHandler.removeMessages(LONG_PRESS);
						mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT
							 + LONGPRESS_TIMEOUT);
					}
					mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT
						);
					handled |= mListener.onDown(ev);
					break;
				}

				case android.view.MotionEvent.ACTION_MOVE:
				{
					if (mInLongPress || (mIgnoreMultitouch && ev.getPointerCount() > 1))
					{
						break;
					}
					float scrollX = mLastMotionX - x;
					float scrollY = mLastMotionY - y;
					if (mIsDoubleTapping)
					{
						// Give the move events of the double-tap
						handled |= mDoubleTapListener.onDoubleTapEvent(ev);
					}
					else
					{
						if (mAlwaysInTapRegion)
						{
							int deltaX = (int)(x - mCurrentDownEvent.getX());
							int deltaY = (int)(y - mCurrentDownEvent.getY());
							int distance = (deltaX * deltaX) + (deltaY * deltaY);
							if (distance > mTouchSlopSquare)
							{
								handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
								mLastMotionX = x;
								mLastMotionY = y;
								mAlwaysInTapRegion = false;
								mHandler.removeMessages(TAP);
								mHandler.removeMessages(SHOW_PRESS);
								mHandler.removeMessages(LONG_PRESS);
							}
							if (distance > mBiggerTouchSlopSquare)
							{
								mAlwaysInBiggerTapRegion = false;
							}
						}
						else
						{
							if ((System.Math.Abs(scrollX) >= 1) || (System.Math.Abs(scrollY) >= 1))
							{
								handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
								mLastMotionX = x;
								mLastMotionY = y;
							}
						}
					}
					break;
				}

				case android.view.MotionEvent.ACTION_UP:
				{
					mStillDown = false;
					android.view.MotionEvent currentUpEvent = android.view.MotionEvent.obtain(ev);
					if (mIsDoubleTapping)
					{
						// Finally, give the up event of the double-tap
						handled |= mDoubleTapListener.onDoubleTapEvent(ev);
					}
					else
					{
						if (mInLongPress)
						{
							mHandler.removeMessages(TAP);
							mInLongPress = false;
						}
						else
						{
							if (mAlwaysInTapRegion)
							{
								handled = mListener.onSingleTapUp(ev);
							}
							else
							{
								// A fling must travel the minimum tap distance
								android.view.VelocityTracker velocityTracker = mVelocityTracker;
								velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
								float velocityY = velocityTracker.getYVelocity();
								float velocityX = velocityTracker.getXVelocity();
								if ((System.Math.Abs(velocityY) > mMinimumFlingVelocity) || (System.Math.Abs(velocityX
									) > mMinimumFlingVelocity))
								{
									handled = mListener.onFling(mCurrentDownEvent, ev, velocityX, velocityY);
								}
							}
						}
					}
					if (mPreviousUpEvent != null)
					{
						mPreviousUpEvent.recycle();
					}
					// Hold the event we obtained above - listeners may have changed the original.
					mPreviousUpEvent = currentUpEvent;
					mVelocityTracker.recycle();
					mVelocityTracker = null;
					mIsDoubleTapping = false;
					mHandler.removeMessages(SHOW_PRESS);
					mHandler.removeMessages(LONG_PRESS);
					break;
				}

				case android.view.MotionEvent.ACTION_CANCEL:
				{
					cancel();
					break;
				}
			}
			if (!handled && mInputEventConsistencyVerifier != null)
			{
				mInputEventConsistencyVerifier.onUnhandledEvent(ev, 0);
			}
			return handled;
		}