ImageView jumping while dragging. getX () and getY () are hops

I created an onTouchListener to drag and drop Views. If you use getRawX() and getRawY() , images smoothly drag and drop. The problem is that the image will jump to the second pointer when you place the second pointer down, then raise the first pointer.

This onTouchListener is trying to fix this problem by tracking pointerId . The problem with this onTouchListener is dragging and dropping the ImageView, the ImageView is jumping around pretty crazy. The values getX() and getY() moved.

I feel like doing it right. I do not want to write a custom view for this, because I already implemented a scaleGestureDetector and wrote my own rotateGestureDetector, which works. Everything works fine, but I need to fix the problem that I get when using getRawX() and getRawY() .

Does anyone know what I'm doing wrong here?

Here is 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 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 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); 
+6
source share
3 answers

The problem was simple but unexpected. getRawX/Y() returns the absolute coordinates, and getX/Y() returns the coordinates relative to the view. I would move the view, reset lastX/Y , and the image would no longer be in the same place, so when I get the new values, they will be disabled. In this case, I only needed where I originally clicked the image (not in the case of using `getRawX / Y ').

So, the solution was to simply remove the following:

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

I hope this helps someone in the future because I saw others with this problem and they had similar code for me (reset lastX/Y )

+10
source

I have one piece of advice and think this will help.

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

What should you use? requestLayout() : The measurement and layout process is in requestLayout() . and I think requestLayout() will be called when setLayoutParams() called;

So try removing v.invalidate()

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

0
source

After many studies, I found this to be a problem, getRawX is absolute, and getX is relative. so use this to convert one to another

 //RawX = getX + View.getX event.getRawX == event.getX(event.findPointerIndex(ptrID1))+view.getX() 
0
source

Source: https://habr.com/ru/post/948957/


All Articles