I my app, I have an element that requires the user to move it around on the screen, and to do this I am using a RelativeLayout and on onTouchListener.
The problem that I am having, is that inside of my onTouchListener
, I am getting some weird results for getX()
and getY()
.
I added the following line of code into my onTouch()
-> ACTION_MOVE
block:
Log.v("example", "Touch: {x:" + event.getX() + " } {y:" + event.getY() + "}");
Below are my LogCat results.
04-29 03:16:11.000: V/myApp(24188): Touch Down!
04-29 03:16:11.057: V/myApp(24188): Touch: {x:69.78699 } {y:107.774216}
04-29 03:16:11.103: V/myApp(24188): Touch: {x:77.86926 } {y:173.37648}
04-29 03:16:11.158: V/myApp(24188): Touch: {x:69.78699 } {y:108.781845}
04-29 03:16:11.205: V/myApp(24188): Touch: {x:77.86926 } {y:174.38597}
04-29 03:16:11.463: V/myApp(24188): Touch: {x:69.78699 } {y:109.64778}
04-29 03:16:11.502: V/myApp(24188): Touch: {x:77.86926 } {y:175.62172}
04-29 03:16:11.596: V/myApp(24188): Touch: {x:69.23099 } {y:109.40666}
04-29 03:16:11.654: V/myApp(24188): Touch Up!
As you can see, moving my finger very slowly in a straight line, I get a jumpy result, where the correct coordinates are actually every other line.
This is resulting in my view jumping back and fourth between the desired position and the offset position as i drag it across the screen.
I have added in checks to be sure that I am only creating a single element, and this this listener is not being called from anywhere other than this single view.
Has anyone else seen this problem before, and have any insight as to what I can do to fix it?
EDIT
View.OnTouchListener onTouch = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d("example", "Touch down");
break;
case MotionEvent.ACTION_UP:
Log.d("example", "Touch up");
break;
case MotionEvent.ACTION_MOVE:
Log.v("example", "Touch: {x:" + event.getX() + " } {y:" + event.getY() + "}");
}
return true;
}
};
I was able to solve this problem by using event.getRawX()
, and event.getRawY()
.
Do you return true inside onTouch() after processing the ACTION_MOVE event? Moreover, as the Android official Reference explains, "For efficiency motion events may batch together multiple movement samples within a single object". So you should use getX() and getY() only to retrieve the last coordinates. To access earlier coordinates you can use the methods getHistoricalX(int) and getHistoricalY(int). For more informations, read the official reference.
MotionEvent will sometimes return absolute X and Y coordinates relative to the view, and sometimes relative coordinates to the previous motion event.
getRawX() and getRawY() that is guaranteed to return absolute coordinates, relative to the device screen.
While getX() and getY(), should return you coordinates, relative to the View, that dispatched them.
reason behind
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With