我创建了一个用于拖动视图的OntouchListener。如果使用getRawX()getRawY(),图像将平滑拖动。问题是,当您向下放置第二个指针,然后抬起第一个指针时,图像将跳到第二个指针。
这个OntouchListener试图通过跟踪pointerId来解决这个问题。这个OntouchListener的问题是在拖动ImageView时,ImageView会疯狂地跳跃。getX()getY()值会跳转。
我觉得我做得对。我不想为此编写自定义视图,因为我已经实现了scalegesturedector并编写了一个自定义rotategesturedector。一切正常,但我需要解决使用getRawX()getRawY()时遇到的问题。
有人知道我做错了什么吗?
这是我的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

08-07 00:56