Example #1
0
		/// <summary>
		/// Transforms a motion event into the coordinate space of a particular child view,
		/// filters out irrelevant pointer ids, and overrides its action if necessary.
		/// </summary>
		/// <remarks>
		/// Transforms a motion event into the coordinate space of a particular child view,
		/// filters out irrelevant pointer ids, and overrides its action if necessary.
		/// If child is null, assumes the MotionEvent will be sent to this ViewGroup instead.
		/// </remarks>
		private bool dispatchTransformedTouchEvent(android.view.MotionEvent @event, bool 
			cancel, android.view.View child, int desiredPointerIdBits)
		{
			bool handled;
			// Canceling motions is a special case.  We don't need to perform any transformations
			// or filtering.  The important part is the action, not the contents.
			int oldAction = @event.getAction();
			if (cancel || oldAction == android.view.MotionEvent.ACTION_CANCEL)
			{
				@event.setAction(android.view.MotionEvent.ACTION_CANCEL);
				if (child == null)
				{
					handled = base.dispatchTouchEvent(@event);
				}
				else
				{
					handled = child.dispatchTouchEvent(@event);
				}
				@event.setAction(oldAction);
				return handled;
			}
			// Calculate the number of pointers to deliver.
			int oldPointerIdBits = @event.getPointerIdBits();
			int newPointerIdBits = oldPointerIdBits & desiredPointerIdBits;
			// If for some reason we ended up in an inconsistent state where it looks like we
			// might produce a motion event with no pointers in it, then drop the event.
			if (newPointerIdBits == 0)
			{
				return false;
			}
			// If the number of pointers is the same and we don't need to perform any fancy
			// irreversible transformations, then we can reuse the motion event for this
			// dispatch as long as we are careful to revert any changes we make.
			// Otherwise we need to make a copy.
			android.view.MotionEvent transformedEvent;
			if (newPointerIdBits == oldPointerIdBits)
			{
				if (child == null || child.hasIdentityMatrix())
				{
					if (child == null)
					{
						handled = base.dispatchTouchEvent(@event);
					}
					else
					{
						float offsetX = mScrollX - child.mLeft;
						float offsetY = mScrollY - child.mTop;
						@event.offsetLocation(offsetX, offsetY);
						handled = child.dispatchTouchEvent(@event);
						@event.offsetLocation(-offsetX, -offsetY);
					}
					return handled;
				}
				transformedEvent = android.view.MotionEvent.obtain(@event);
			}
			else
			{
				transformedEvent = @event.split(newPointerIdBits);
			}
			// Perform any necessary transformations and dispatch.
			if (child == null)
			{
				handled = base.dispatchTouchEvent(transformedEvent);
			}
			else
			{
				float offsetX = mScrollX - child.mLeft;
				float offsetY = mScrollY - child.mTop;
				transformedEvent.offsetLocation(offsetX, offsetY);
				if (!child.hasIdentityMatrix())
				{
					transformedEvent.transform(child.getInverseMatrix());
				}
				handled = child.dispatchTouchEvent(transformedEvent);
			}
			// Done.
			transformedEvent.recycle();
			return handled;
		}
Example #2
0
		/// <summary>
		/// Dispatches a generic pointer event to a child, taking into account
		/// transformations that apply to the child.
		/// </summary>
		/// <remarks>
		/// Dispatches a generic pointer event to a child, taking into account
		/// transformations that apply to the child.
		/// </remarks>
		/// <param name="event">The event to send.</param>
		/// <param name="child">The view to send the event to.</param>
		/// <returns>
		/// 
		/// <code>true</code>
		/// if the child handled the event.
		/// </returns>
		private bool dispatchTransformedGenericPointerEvent(android.view.MotionEvent @event
			, android.view.View child)
		{
			float offsetX = mScrollX - child.mLeft;
			float offsetY = mScrollY - child.mTop;
			bool handled;
			if (!child.hasIdentityMatrix())
			{
				android.view.MotionEvent transformedEvent = android.view.MotionEvent.obtain(@event
					);
				transformedEvent.offsetLocation(offsetX, offsetY);
				transformedEvent.transform(child.getInverseMatrix());
				handled = child.dispatchGenericMotionEvent(transformedEvent);
				transformedEvent.recycle();
			}
			else
			{
				@event.offsetLocation(offsetX, offsetY);
				handled = child.dispatchGenericMotionEvent(@event);
				@event.offsetLocation(-offsetX, -offsetY);
			}
			return handled;
		}