我有一个应用程序,我通过点绘制线条以形成多边形,我希望能够使多边形的四个角可以移动,我将此代码放在我为绘制多边形而创建的自定义视图中:
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文档如何处理此事件,所以我不确定问题是什么,或者如何找到它。我的问题是,我究竟做错了什么导致移动事件无法被接收?
答案 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