[英]Jumping ImageView while dragging. getX() and getY() values are jumping
我已经创建了一个用于拖动视图的onTouchListener。 如果我使用getRawX()
和getRawY()
图像会平滑地拖动。 问题是,当您向下放置第二个指针然后抬起第一个指针时,图像将跳转到第二个指针。
这onTouchListener试图通过跟踪来解决这个问题pointerId
。 这个onTouchListener的问题是在拖动ImageView时,ImageView非常疯狂地跳转。 getX()
和getY()
值跳转。
我觉得我正确地做到了这一点。 我不想为此编写自定义视图,因为我已经实现了scaleGestureDetector并编写了一个有效的自定义rotateGestureDetector。 一切正常但我需要解决使用getRawX()
和getRawY()
时getRawX()
的问题。
有谁知道我在这里做错了什么?
这是我的onTouchListener:
final View.OnTouchListener onTouchListener = new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
relativeLayoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
final int action = event.getAction();
switch (action & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
{
final float x = event.getX();
final float y = event.getY();
// Where the user started the drag
lastX = x;
lastY = y;
activePointerId = event.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE:
{
// Where the user's finger is during the drag
final int pointerIndex = event.findPointerIndex(activePointerId);
final float x = event.getX(pointerIndex);
final float y = event.getY(pointerIndex);
// Calculate change in x and change in y
final float dx = x - lastX;
final float dy = y - lastY;
// Update the margins to move the view
relativeLayoutParams.leftMargin += dx;
relativeLayoutParams.topMargin += dy;
v.setLayoutParams(relativeLayoutParams);
// Save where the user's finger was for the next ACTION_MOVE
lastX = x;
lastY = y;
v.invalidate();
break;
}
case MotionEvent.ACTION_UP:
{
activePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL:
{
activePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP:
{
// Extract the index of the pointer that left the touch sensor
final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = event.getPointerId(pointerIndex);
if(pointerId == activePointerId)
{
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
lastX = (int) event.getX(newPointerIndex);
lastY = (int) event.getY(newPointerIndex);
activePointerId = event.getPointerId(newPointerIndex);
}
break;
}
}
return true;
}
};
image1.setOnTouchListener(onTouchListener);
问题很简单,但出人意料。 getRawX/Y()
返回绝对坐标,而getX/Y()
返回相对于视图的坐标。 我会移动视图,重置lastX/Y
,图像将不再在同一个位置,所以当我得到新的值时,它们将被关闭。 在这种情况下,我只需要我最初按下图像的位置(不是使用`getRawX / Y'时的情况)。
因此,解决方案是简单地删除以下内容:
// Save where the user's finger was for the next ACTION_MOVE
lastX = x;
lastY = y;
我希望这将有助于将来的lastX/Y
人,因为我见过其他人有这个问题,他们有类似的代码给我(重置lastX/Y
)
我有一个提示,并认为它会有所帮助。
invalidate() : does only redrawing a view,doesn't change view size/position.
你应该使用的是requestLayout()
:测量和布局过程。 我认为调用setLayoutParams()
时会调用requestLayout()
setLayoutParams()
;
所以尝试删除v.invalidate()
或者尝试使用view.layout(left,top,right,bottom)
方法而不是设置layoutParams。
经过大量的研究,我发现这是问题,getRawX是绝对的,getX是相对于视图。 因此使用它来改变一个到另一个
//RawX = getX + View.getX
event.getRawX == event.getX(event.findPointerIndex(ptrID1))+view.getX()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.