Xamarin MotionEventActions.Move永远不会在自定义视图onTouch事件中被击中?

时间:2017-05-08 23:55:01

标签: c# android xamarin xamarin.android

我有一个应用程序,我通过点绘制线条以形成多边形,我希望能够使多边形的四个角可以移动,我将此代码放在我为绘制多边形而创建的自定义视图中:

public override bool OnTouchEvent(MotionEvent e)
{
        MotionEventActions action = e.Action;

        float x = 0.0f;
        float y = 0.0f;
        float radius = 20.0f;

        // Get the current pointer index
        int tempPointerIndex = e.ActionIndex;
        x = e.GetX(tempPointerIndex);
        y = e.GetY(tempPointerIndex);

        // For each point, check to see if the touch fell within the bounds of the circle
        for (int i = 0; i < _points.Length; i++)
        {
            if((x >= _points[i].X - radius && x <= _points[i].X + 20) || 
               (y >= _points[i].Y - radius && y >= _points[i].Y + 20))
            {
                switch (action)
                {
                    case MotionEventActions.Down:
                    {


                        // Get the current x/y when not moving so we can calculate the delta x/y in 
                        // move events
                        lastX = x;
                        lastY = y;

                        // Set the global active pointer index
                        activePointerId = e.GetPointerId(0);

                        break;
                    }
                    case MotionEventActions.Move:
                    {

                            int pointerIndex = e.FindPointerIndex(activePointerId);
                            x = e.GetX(pointerIndex);
                            y = e.GetY(pointerIndex);

                            // Find the delta x/y
                            float deltaX = x - lastX;
                            float deltaY = y - lastY;

                            // Move the selected skew handle by the delta x/y
                            _points[i].X += deltaX;
                            _points[i].Y += deltaY;

                            // Force a redraw
                            this.Invalidate();

                            break;
                    }
                    case MotionEventActions.Up:
                    {
                        // Invalidate the active pointer index
                        activePointerId = global::Android.Views.MotionEvent.InvalidPointerId;
                        break;
                    }
                    case MotionEventActions.Cancel:
                    {
                        // Invalidate the active pointer index
                        activePointerId = global::Android.Views.MotionEvent.InvalidPointerId;
                        break;
                    }
                    case MotionEventActions.PointerUp:
                    {
                            int pointerIndex = e.ActionIndex;
                            int pointerId = e.GetPointerId(pointerIndex);

                            if(pointerId == activePointerId)
                            {
                                // Active pointer going up, choose new active pointer and adjust accordingly
                                int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                                lastX = e.GetX(newPointerIndex);
                                lastY = e.GetY(newPointerIndex);
                                activePointerId = e.GetPointerId(newPointerIndex);
                            }

                        break;
                    }
                }
            }
        }
        return base.OnTouchEvent(e);
    }

MotionEventActions.Move的情况似乎永远不会被击中,事实上,唯一似乎被击中的事件是当我最初达到一个点时的击倒事件。此外,检查点的边界的条件肯定是有效的,我已经多次测试了,所以这也不是问题,我不确定我是否可能错误地检查了事件,但是据我所知,这是Xamarin和Android文档如何处理此事件,所以我不确定问题是什么,或者如何找到它。我的问题是,我究竟做错了什么导致移动事件无法被接收?

1 个答案:

答案 0 :(得分:3)

一旦您确定某个点是否在用户触摸的范围内,就开始从true返回OnTouchEvent,直到您获得Up,这样所有未来触摸事件会在您的自定义Move上成为View个事件,并且不会重定向到View的父级。

向下/向上/向上移动触摸事件逻辑:

public override bool OnTouchEvent(MotionEvent e)
{
    x = e.GetX(e.ActionIndex);
    y = e.GetY(e.ActionIndex);
    Log.Debug(TAG, $"{e.Action} : {x} : {y}" );
    if (e.Action == MotionEventActions.Down)
    {
        if (true) // some check if the x/y touch is on or near a moveable point, isDraggingPoint becomes true
            isDraggingPoint = true;
        else 
            isDraggingPoint = false;
    }
    if (e.Action == MotionEventActions.Move)
    {
        // move your Point, x/y touch for draggingPoint, update display, etc... 
    }
    if (e.Action == MotionEventActions.Up)
    {
        // save the final x/y touch for draggingPoint, update display, etc... 
        isDraggingPoint = false;
    }
    return isDraggingPoint;
}

输出:

[CustomView] Down : 358.5332 : 234.6167
[CustomView] Move : 358.5332 : 234.6167
[CustomView] Move : 352.5305 : 238.6241
[CustomView] Move : 334.8269 : 237.3517
[CustomView] Move : 360.5305 : 246.6073
[CustomView] Move : 360.5305 : 246.6073
[CustomView] Up : 360.5305 : 246.6073