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);
        }
Example #2
0
        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;
            }
        }
Example #3
0
        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;
            }
        }