public override bool DispatchTouchEvent(MotionEvent e) { if (e.Action == MotionEventActions.Down) { _downTime = DateTime.UtcNow; _downPosition = new Point(e.RawX, e.RawY); } if (e.Action != MotionEventActions.Up) { return(base.DispatchTouchEvent(e)); } global::Android.Views.View currentView = Context.GetActivity().CurrentFocus; bool result = base.DispatchTouchEvent(e); do { if (!(currentView is EditText)) { break; } global::Android.Views.View newCurrentView = Context.GetActivity().CurrentFocus; if (currentView != newCurrentView) { break; } double distance = _downPosition.Distance(new Point(e.RawX, e.RawY)); if (distance > Context.ToPixels(20) || DateTime.UtcNow - _downTime > TimeSpan.FromMilliseconds(200)) { break; } var location = new int[2]; currentView.GetLocationOnScreen(location); float x = e.RawX + currentView.Left - location[0]; float y = e.RawY + currentView.Top - location[1]; var rect = new Rectangle(currentView.Left, currentView.Top, currentView.Width, currentView.Height); if (rect.Contains(x, y)) { break; } Context.HideKeyboard(currentView); Context.GetActivity().Window.DecorView.ClearFocus(); } while (false); return(result); }
void CheckForBoundaryHop(int id, Point pointerLocation) { TouchEffect touchEffectHit = null; foreach (global::Android.Views.View view in viewDictionary.Keys) { // Get the view rectangle try { view.GetLocationOnScreen(twoIntArray); } catch // System.ObjectDisposedException: Cannot access a disposed object. { continue; } Rectangle viewRect = new Rectangle(twoIntArray[0], twoIntArray[1], view.Width, view.Height); if (viewRect.Contains(pointerLocation)) { touchEffectHit = viewDictionary[view]; } } if (touchEffectHit != idToEffectDictionary[id]) { if (idToEffectDictionary[id] != null) { FireEvent(idToEffectDictionary[id], id, TouchActionType.Exited, pointerLocation, true); } if (touchEffectHit != null) { FireEvent(touchEffectHit, id, TouchActionType.Entered, pointerLocation, true); } idToEffectDictionary[id] = touchEffectHit; } }
void OnTouch(object sender, global::Android.Views.View.TouchEventArgs args) { // Two object common to all the events global::Android.Views.View senderView = sender as global::Android.Views.View; MotionEvent motionEvent = args.Event; // Get the pointer index int pointerIndex = motionEvent.ActionIndex; // Get the id that identifies a finger over the course of its progress int id = motionEvent.GetPointerId(pointerIndex); senderView.GetLocationOnScreen(twoIntArray); Point screenPointerCoords = new Point(twoIntArray[0] + motionEvent.GetX(pointerIndex), twoIntArray[1] + motionEvent.GetY(pointerIndex)); // Use ActionMasked here rather than Action to reduce the number of possibilities switch (args.Event.ActionMasked) { case MotionEventActions.Down: case MotionEventActions.PointerDown: FireEvent(this, id, TouchActionType.Pressed, screenPointerCoords, true); idToEffectDictionary.Add(id, this); capture = libTouchEffect.Capture; break; case MotionEventActions.Move: // Multiple Move events are bundled, so handle them in a loop for (pointerIndex = 0; pointerIndex < motionEvent.PointerCount; pointerIndex++) { id = motionEvent.GetPointerId(pointerIndex); if (capture) { senderView.GetLocationOnScreen(twoIntArray); screenPointerCoords = new Point(twoIntArray[0] + motionEvent.GetX(pointerIndex), twoIntArray[1] + motionEvent.GetY(pointerIndex)); FireEvent(this, id, TouchActionType.Moved, screenPointerCoords, true); } else { CheckForBoundaryHop(id, screenPointerCoords); if (idToEffectDictionary[id] != null) { FireEvent(idToEffectDictionary[id], id, TouchActionType.Moved, screenPointerCoords, true); } } } break; case MotionEventActions.Up: case MotionEventActions.Pointer1Up: if (capture) { FireEvent(this, id, TouchActionType.Released, screenPointerCoords, false); } else { CheckForBoundaryHop(id, screenPointerCoords); if (idToEffectDictionary[id] != null) { FireEvent(idToEffectDictionary[id], id, TouchActionType.Released, screenPointerCoords, false); } } idToEffectDictionary.Remove(id); break; case MotionEventActions.Cancel: if (capture) { FireEvent(this, id, TouchActionType.Cancelled, screenPointerCoords, false); } else { if (idToEffectDictionary[id] != null) { FireEvent(idToEffectDictionary[id], id, TouchActionType.Cancelled, screenPointerCoords, false); } } idToEffectDictionary.Remove(id); break; } }