Пример #1
0
        public override bool DispatchTouchEvent(MotionEvent e)
        {
            bool ret = false;

            // vérifi que le InfoWindows est affiché
            if (_marker != null && _marker.IsInfoWindowShown && _map != null && _infoWindow != null)
            {
                // obtient la position du marker à l'écran
                Point point = _map.Projection.ToScreenLocation(_marker.Position);

                // ajustement du clique pour un pin Seekios
                MotionEvent seekiosRefresh = MotionEvent.ObtainNoHistory(e);
                seekiosRefresh.OffsetLocation(
                    -point.X + (_infoWindow.Width / 2),
                    -point.Y + _infoWindow.Height + _heightSeekios);   // 130 = la hauteur du pin seekios

                // ajustement du clique pour un pin Marker
                MotionEvent copyEvMarker = MotionEvent.ObtainNoHistory(e);
                copyEvMarker.OffsetLocation(
                    -point.X + (_infoWindow.Width / 2),
                    -point.Y + _infoWindow.Height + _heightMarker);    // 35 = la hauteur du pin marker

                // dispatch le MotionEvent ajusté vers le InfoWindow
                ret = _infoWindow.DispatchTouchEvent(seekiosRefresh);
                ret = _infoWindow.DispatchTouchEvent(copyEvMarker);
            }

            return(ret || base.DispatchTouchEvent(e));
        }
Пример #2
0
        private MotionEvent ObtainMotionEvent(MotionEvent source, MotionEventActions action)
        {
            MotionEvent ev = MotionEvent.ObtainNoHistory(source);

            ev.Action = action;
            return(ev);
        }
Пример #3
0
        private void SendFakeEvent(MotionEvent e, MotionEventActions forcedAction)
        {
            var fake_event = MotionEvent.ObtainNoHistory(e);

            fake_event.Action = forcedAction;
            ContentView.ForceHandleTouchEvent(fake_event);
            fake_event.Recycle();
        }
Пример #4
0
 /**
  * Duplicate touch events to child views.
  * We want to dispatch a down motion event and the move events to
  * child views, but calling dispatchTouchEvent() causes StackOverflowError.
  * Therefore we do it manually.
  *
  * @param ev            motion event to be passed to children
  * @param pendingEvents pending events like ACTION_DOWN. This will be passed to the children before ev
  */
 private void DuplicateTouchEventForChildren(MotionEvent ev, params MotionEvent[] pendingEvents)
 {
     if (ev == null)
     {
         return;
     }
     for (int i = ChildCount - 1; 0 <= i; i--)
     {
         View childView = GetChildAt(i);
         if (childView != null)
         {
             Rect childRect = new Rect();
             childView.GetHitRect(childRect);
             MotionEvent event2 = MotionEvent.ObtainNoHistory(ev);
             if (!childRect.Contains((int)event2.GetX(), (int)event2.GetY()))
             {
                 continue;
             }
             float offsetX  = -childView.Left;
             float offsetY  = -childView.Top;
             bool  consumed = false;
             if (pendingEvents != null)
             {
                 foreach (MotionEvent pe in pendingEvents)
                 {
                     if (pe != null)
                     {
                         MotionEvent peAdjusted = MotionEvent.ObtainNoHistory(pe);
                         peAdjusted.OffsetLocation(offsetX, offsetY);
                         consumed |= childView.DispatchTouchEvent(peAdjusted);
                     }
                 }
             }
             event2.OffsetLocation(offsetX, offsetY);
             consumed |= childView.DispatchTouchEvent(event2);
             if (consumed)
             {
                 break;
             }
         }
     }
 }
Пример #5
0
        public override bool OnInterceptTouchEvent(MotionEvent ev)
        {
            if (_mTouchInterceptionListener == null)
            {
                return(false);
            }

            // In here, we must initialize touch state variables
            // and ask if we should intercept this event.
            // Whether we should intercept or not is kept for the later event handling.
            switch (ev.ActionMasked)
            {
            case MotionEventActions.Down:
                _mInitialPoint             = new PointF(ev.GetX(), ev.GetY());
                _mPendingDownMotionEvent   = MotionEvent.ObtainNoHistory(ev);
                _mDownMotionEventPended    = true;
                _mIntercepting             = _mTouchInterceptionListener.ShouldInterceptTouchEvent(ev, false, 0, 0);
                _mBeganFromDownMotionEvent = _mIntercepting;
                _mChildrenEventsCanceled   = false;
                return(_mIntercepting);

            case MotionEventActions.Move:
                // ACTION_MOVE will be passed suddenly, so initialize to avoid exception.
                if (_mInitialPoint == null)
                {
                    _mInitialPoint = new PointF(ev.GetX(), ev.GetY());
                }

                // diffX and diffY are the origin of the motion, and should be difference
                // from the position of the ACTION_DOWN event occurred.
                float diffX = ev.GetX() - _mInitialPoint.X;
                float diffY = ev.GetY() - _mInitialPoint.Y;
                _mIntercepting = _mTouchInterceptionListener.ShouldInterceptTouchEvent(ev, true, diffX, diffY);
                return(_mIntercepting);
            }
            return(false);
        }
        public override bool OnTouchEvent(MotionEvent ev)
        {
            if (_mCallbacks != null)
            {
                switch (ev.ActionMasked)
                {
                case MotionEventActions.Up:
                case MotionEventActions.Cancel:
                    _mIntercepted = false;
                    _mDragging    = false;
                    _mCallbacks.OnUpOrCancelMotionEvent(_mScrollState);
                    break;

                case MotionEventActions.Move:
                    if (_mPrevMoveEvent == null)
                    {
                        _mPrevMoveEvent = ev;
                    }
                    float diffY = ev.GetY() - _mPrevMoveEvent.GetY();
                    _mPrevMoveEvent = MotionEvent.ObtainNoHistory(ev);
                    if (GetCurrentScrollY() - diffY <= 0)
                    {
                        // Can't scroll anymore.

                        if (_mIntercepted)
                        {
                            // Already dispatched ACTION_DOWN event to parents, so stop here.
                            return(false);
                        }

                        // Apps can set the interception target other than the direct parent.
                        ViewGroup parent;
                        if (_mTouchInterceptionViewGroup == null)
                        {
                            parent = (ViewGroup)Parent;
                        }
                        else
                        {
                            parent = _mTouchInterceptionViewGroup;
                        }

                        // Get offset to parents. If the parent is not the direct parent,
                        // we should aggregate offsets from all of the parents.
                        float offsetX = 0;
                        float offsetY = 0;
                        for (View v = this; v != null && v != parent; v = (View)v.Parent)
                        {
                            offsetX += v.Left - v.ScrollX;
                            offsetY += v.Top - v.ScrollY;
                        }

                        MotionEvent eventHistoryLess = MotionEvent.ObtainNoHistory(ev);
                        eventHistoryLess.OffsetLocation(offsetX, offsetY);

                        if (parent.OnInterceptTouchEvent(eventHistoryLess))
                        {
                            _mIntercepted = true;

                            // If the parent wants to intercept ACTION_MOVE events,
                            // we pass ACTION_DOWN event to the parent
                            // as if these touch events just have began now.
                            eventHistoryLess.Action = MotionEventActions.Down;

                            // Return this onTouchEvent() first and set ACTION_DOWN event for parent
                            // to the queue, to keep events sequence.
                            Post(() => parent.DispatchTouchEvent(eventHistoryLess));
                            return(false);
                        }
                        // Even when this can't be scrolled anymore,
                        // simply returning false here may cause subView's click,
                        // so delegate it to super.
                        return(base.OnTouchEvent(ev));
                    }
                    break;
                }
            }
            return(base.OnTouchEvent(ev));
        }
Пример #7
0
        public override bool OnTouchEvent(MotionEvent ev)
        {
            if (_mTouchInterceptionListener != null)
            {
                switch (ev.ActionMasked)
                {
                case MotionEventActions.Down:
                    if (_mIntercepting)
                    {
                        _mTouchInterceptionListener.OnDownMotionEvent(ev);
                        DuplicateTouchEventForChildren(ev);
                        return(true);
                    }
                    break;

                case MotionEventActions.Move:
                    // ACTION_MOVE will be passed suddenly, so initialize to avoid exception.
                    if (_mInitialPoint == null)
                    {
                        _mInitialPoint = new PointF(ev.GetX(), ev.GetY());
                    }

                    // diffX and diffY are the origin of the motion, and should be difference
                    // from the position of the ACTION_DOWN event occurred.
                    float diffX = ev.GetX() - _mInitialPoint.X;
                    float diffY = ev.GetY() - _mInitialPoint.Y;
                    _mIntercepting = _mTouchInterceptionListener.ShouldInterceptTouchEvent(ev, true, diffX, diffY);
                    if (_mIntercepting)
                    {
                        // If this layout didn't receive ACTION_DOWN motion event,
                        // we should generate ACTION_DOWN event with current position.
                        if (!_mBeganFromDownMotionEvent)
                        {
                            _mBeganFromDownMotionEvent = true;

                            MotionEvent event2 = MotionEvent.ObtainNoHistory(_mPendingDownMotionEvent);
                            event2.SetLocation(ev.GetX(), ev.GetY());
                            _mTouchInterceptionListener.OnDownMotionEvent(event2);

                            _mInitialPoint = new PointF(ev.GetX(), ev.GetY());
                            diffX          = diffY = 0;
                        }

                        // Children's touches should be canceled
                        if (!_mChildrenEventsCanceled)
                        {
                            _mChildrenEventsCanceled = true;
                            DuplicateTouchEventForChildren(ObtainMotionEvent(ev, MotionEventActions.Cancel));
                        }

                        _mTouchInterceptionListener.OnMoveMotionEvent(ev, diffX, diffY);

                        // If next mIntercepting become false,
                        // then we should generate fake ACTION_DOWN event.
                        // Therefore we set pending flag to true as if this is a down motion event.
                        _mDownMotionEventPended = true;

                        // Whether or not this event is consumed by the listener,
                        // assume it consumed because we declared to intercept the event.
                        return(true);
                    }
                    if (_mDownMotionEventPended)
                    {
                        _mDownMotionEventPended = false;
                        MotionEvent event2 = MotionEvent.ObtainNoHistory(_mPendingDownMotionEvent);
                        event2.SetLocation(ev.GetX(), ev.GetY());
                        DuplicateTouchEventForChildren(ev, event2);
                    }
                    else
                    {
                        DuplicateTouchEventForChildren(ev);
                    }

                    // If next mIntercepting become true,
                    // then we should generate fake ACTION_DOWN event.
                    // Therefore we set beganFromDownMotionEvent flag to false
                    // as if we haven't received a down motion event.
                    _mBeganFromDownMotionEvent = false;

                    // Reserve children's click cancellation here if they've already canceled
                    _mChildrenEventsCanceled = false;
                    break;

                case MotionEventActions.Up:
                case MotionEventActions.Cancel:
                    _mBeganFromDownMotionEvent = false;
                    if (_mIntercepting)
                    {
                        _mTouchInterceptionListener.OnUpOrCancelMotionEvent(ev);
                    }

                    // Children's touches should be canceled regardless of
                    // whether or not this layout intercepted the consecutive motion events.
                    if (!_mChildrenEventsCanceled)
                    {
                        _mChildrenEventsCanceled = true;
                        if (_mDownMotionEventPended)
                        {
                            _mDownMotionEventPended = false;
                            MotionEvent event2 = MotionEvent.ObtainNoHistory(_mPendingDownMotionEvent);
                            event2.SetLocation(ev.GetX(), ev.GetY());
                            DuplicateTouchEventForChildren(ev, event2);
                        }
                        else
                        {
                            DuplicateTouchEventForChildren(ev);
                        }
                    }
                    return(true);
                }
            }
            return(base.OnTouchEvent(ev));
        }