Jumping ImageView while dragging. getX() and getY() values are jumping

我的未来我决定 提交于 2019-12-06 00:46:13

问题


I've created an onTouchListener for dragging Views. Images drag smoothly if I use getRawX() and getRawY(). The problem with that is the image will jump to the second pointer when you place a second pointer down then lift the first pointer.

This onTouchListener attempts to fix that issue by keeping track of the pointerId. The problem with this onTouchListener is while dragging an ImageView, the ImageView jumps around pretty crazily. The getX() and getY() values jump around.

I feel like I'm doing this correctly. I don't want to have to write a custom view for this because I've already implemented a scaleGestureDetector and written a custom rotateGestureDetector that work. Everything works fine but I need to fix the issue I get when using getRawX() and getRawY().

Does anybody know what I'm doing wrong here?

Here's my 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);

回答1:


The issue was simple, but unexpected. getRawX/Y() returns absolute coordinates, while getX/Y() returns coordinates relative to the view. I would move the view, reset lastX/Y, and the image wouldn't be in the same spot anymore so when I get new values they'd be off. In this case I only needed where I originally pressed the image (not the case when using `getRawX/Y').

So, the solution was to simply remove the following:

// Save where the user's finger was for the next ACTION_MOVE
lastX = x;
lastY = y;

I hope this will help somebody in the future, because I've seen others with this problem, and they had similar code to me (resetting lastX/Y)




回答2:


I have One tip & think it will help.

invalidate() : does only redrawing a view,doesn't change view size/position.

What you should use is requestLayout(): does the measuring and layout process. & i think requestLayout() will be called when call setLayoutParams();

So Try by removing v.invalidate()

or try using view.layout(left,top,right,bottom) method instead of setting layoutParams.




回答3:


After a lot of research, I found this to be the issue, getRawX is absolute and getX is relative to view. hence use this to transform one to another

//RawX = getX + View.getX

event.getRawX == event.getX(event.findPointerIndex(ptrID1))+view.getX()


来源:https://stackoverflow.com/questions/17530589/jumping-imageview-while-dragging-getx-and-gety-values-are-jumping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!