I am having an issue with MotionEvent.ACTION_UP The event is called before I lift my finger.
Here is the code I am using. What should I change? Thanks for any help!
public boolean onTouchEvent(MotionEvent e) {
switch(e.getAction()) {
case MotionEvent.ACTION_DOWN:
if(checkColide(e.getX(), e.getY())) {
isFootballTouched = true;
downT = c.MILLISECOND;
downX = e.getX();
}
break;
case MotionEvent.ACTION_MOVE:
//moveFootball(e.getX(), e.getY());
break;
case MotionEvent.ACTION_UP:
upT = c.MILLISECOND;
upX = e.getX();
getVelocity();
break;
}
return false;
}
Try returning true if one of this 3 case occurred
public boolean onTouchEvent(MotionEvent e) {
switch(e.getAction()) {
case MotionEvent.ACTION_DOWN:
if(checkColide(e.getX(), e.getY())) {
isFootballTouched = true;
downT = c.MILLISECOND;
downX = e.getX();
}
return true;
case MotionEvent.ACTION_MOVE:
//moveFootball(e.getX(), e.getY());
return true;
case MotionEvent.ACTION_UP:
upT = c.MILLISECOND;
upX = e.getX();
getVelocity();
return true;
}
return false;
}
Probably you should return true from the onTouchEvent(). Returning false means that you're not interested in receiving events to this View anymore. Hope this helps.
Related
my question can be pretty strange, but I can not understand why my scene is moving back, if I touch the screen elsewhere, please help me figure it out.
https://youtu.be/oKdwqn0HC0Y - in this video record my problem,
To better understand the problem
#Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
return true;
}
switch (event.getPointerCount()) {
case 3:
Log.e("Event", "PointerCount = " +event.getPointerCount());
return mScaleDetector.onTouchEvent(event);
case 2:
Log.e("Event", "PointerCount = " +event.getPointerCount());
return doRotationEvent(event);
case 1:
Log.e("Event", "PointerCount = " +event.getPointerCount());
return doMoveEvent(event);
}
return true;
}
private boolean doMoveEvent(MotionEvent event)
{
final int action = event.getAction();
Log.e("doMoveEvent", "action = " +action);
switch (action) {
case MotionEvent.ACTION_DOWN: {
Log.e("doMoveEvent", "action_down");
final float x = event.getX();
Log.e("doMoveEvent", " x = " +x);
final float y = event.getY();
Log.e("doMoveEvent", " y = " +y);
// Remember where we started
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_MOVE: {
final float x = event.getX();
final float y = event.getY();
// Calculate the distance moved
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
Log.e("doMoveEvent", " DX = " +dx);
Log.e("doMoveEvent", " DY = " +dy);
renderer.angleX += dy;
renderer.angleY += dx;
mLastTouchX = x;
mLastTouchY = y;
// Invalidate to request a redraw
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
}
return true;
}
I solved my problem this way
#Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
final float x = event.getX(); //(NEW)
final float y = event.getY(); //(NEW)
mLastTouchX = x; //(NEW)
mLastTouchY = y; //(NEW)
return true;
}
switch (event.getPointerCount()) {
case 3:
Log.e("Event", "PointerCount = " +event.getPointerCount());
return mScaleDetector.onTouchEvent(event);
case 2:
Log.e("Event", "PointerCount = " +event.getPointerCount());
return doRotationEvent(event);
case 1:
Log.e("Event", "PointerCount = " +event.getPointerCount());
return doMoveEvent(event);
}
return true;
}
Here is my code:
public boolean onTouch(View v, MotionEvent event) {
switch(event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
Log.d("getButtonCode", "catch ACTION_DOWN");
break;
case MotionEvent.ACTION_POINTER_DOWN:
Log.d("getButtonCode", "catch ACTION_POINTER_DOWN");
break;
case MotionEvent.ACTION_POINTER_UP:
Log.d("getButtonCode", "catch ACTION_POINTER_UP");
break;
case MotionEvent.ACTION_UP:
Log.d("getButtonCode", "catch ACTION_UP");
case MotionEvent.ACTION_CANCEL:
Log.d("getButtonCode", "catch ACTION_CANCEL");
case MotionEvent.ACTION_MOVE:
break;
default:
break;
}
return true;
}
and I never catch ACTION_POINTER_DOWN and ACTION_POINTER_UP. If I remove breakfrom ACTION_DOWN, I catch ACTION_POINTER_DOWN always after ACTION_DOWN, even if it is first pointer. I think it should be so: first pointer catch only ACTION_DOWN, every next pointer only ACTION_POINTER_DOWN, if non-primary pointer has gone up, I should catch ACTION_POINTER_UP.
But it doesn't work. What is wrong in my code?
PS: I saw other similar questions, but no answer helped me.
Instead of using a switch statement, I flowed through a series of if statements. This let me test against event.getAction() or event.getActionMasked() and it allowed multiple possible actions through at once.
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
startingX = (int) event.getX();
startingY = (int) event.getY();
}
if(event.getAction() == MotionEvent.ACTION_MOVE) {
int scaleX = 1;
int scaleY = 1;
if(touchStateScale == true){
scaleX = (int) (event.getX(0) - event.getX(1));
scaleY = (int) (event.getY(0) - event.getY(1));
}
int endingX = (int) event.getX();
int endingY = (int) event.getY();
int newX = endingX-startingX;
int newY = endingY-startingY;
((ImageView) v).setImageBitmap(drawNewImageScaled(baseImage, newImageResourceId, newX, newY, scaleX, scaleY));
}
if(event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN){
Log.i(TAG, "second pointer detected");
touchStateScale = true;
}
if (event.getAction() == MotionEvent.ACTION_UP) {
touchStateScale = false;
return false;
}
return true;
}
};
I want to remove the TouchEvent of Button when the User moves out of the Button Area
I have detected the user movement by:
case MotionEvent.ACTION_DOWN:
rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
break;
case MotionEvent.ACTION_MOVE:
if(!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())){
logIt("You are OutSide...");
}
break;
Can Anyone Suggest how to do that...
ANy answer Appreciated...Thks
reWrite code like this :-
case MotionEvent.ACTION_DOWN:
rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
break;
case MotionEvent.ACTION_UP:
if(!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())){
logIt("You are OutSide...");
}
break;
try this...
case MotionEvent.ACTION_DOWN:
rect = new Rect(v.getLeft(), v.getTop(), v.getRight(),v.getBottom());
break;
case MotionEvent.ACTION_MOVE:
if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop()+ (int) event.getY())) {
Log.i(TAG, "You are outside");
return false;
}
break;
and this complete code will give you some idea...
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
rect = new Rect(v.getLeft(), v.getTop(), v.getRight(),v.getBottom());
break;
case MotionEvent.ACTION_MOVE:
if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop()+ (int) event.getY())) {
Log.i(TAG, "You are outside");
return false;
}
break;
}
return true;
}
Simpliest way :
onTouchEvent(MotionEvent event){
...
case MotionEvent.ACTION_MOVE:
event.setAction(MotionEvent.ACTION_UP);
return super.onTouchEvent(event);
...
}
In That case you will reject all next events related on your button.
I have a few polygons on Canvas.
How I can listening click on any from polygons?
I have a method
public void drawPolygon(ChartPolygon polygon) {
List<Point> points = polygon.getPoints();
int size = points.size();
if (size < 2) {
return;
}
Paint polyPaint = new Paint();
polyPaint.setColor(polygon.getColor());
polyPaint.setStyle(Style.FILL);
Path polyPath = new Path();
polyPath.moveTo(points.get(0).getX(), points.get(0).getY());
for (Point point : points) {
polyPath.lineTo(point.getX(), point.getY());
}
canvas.drawPath(polyPath, polyPaint);
}
I would keep a list of Regions. Whenever you draw a new Polygon, use the same Path which you use for drawing also to define a new Region:
Region r = new Region();
r.setPath(path, clip);
regionList.add(r);
clip could be defined e.g. by
Region clip = new Region(0, 0, canvas.getWidth(), canvas.getHeight());
Finally when you detect a touch in your onTouchListener loop over the regionList and check, whether the touched point (given by x and y) is inside the region:
for (int i = 0; i < regionList.size(); i++) {
Region r = regionList.get(i);
if (r.contains(x,y) {
selectedRegionIndex = i;
break;
}
}
Read this post, this post can help you
First one, you can get the position in X and Y of the click event in your screen.
You can implement the onTouchEvent function in the Activity extends
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (topTouchArea.contains(event.getX(), event.getY())) {
currentTouch = TOUCH_TOP;
} else if (RightTouchArea.contains(event.getX(),event.getY())) {
currentTouch = TOUCH_RIGHT;
} else if (LeftTouchArea.contains(event.getX(),event.getY())) {
currentTouch = TOUCH_LEFT;
} else {
return false; //Return false if user touches none of the corners
}
return true;
}
}
Now (always in your onTouchEvent) function, you can evaluate the position and regions of your polygon.
case MotionEvent.ACTION_MOVE:
switch (currentTouch) {
case TOUCH_TOP:
top.x = event.getX();
top.y = event.getY();
invalidate();
return true;
case TOUCH_RIGHT:
Right.x = event.getX();
Right.y = event.getY();
invalidate();
return true;
case TOUCH_LEFT:
Left.x = event.getX();
Left.y = event.getY();
invalidate();
return true;
}
case MotionEvent.ACTION_UP:
switch (currentTouch) {
case TOUCH_TOP:
top.x = event.getX();
top.y = event.getY();
invalidate();
currentTouch = NONE;
return true;
case TOUCH_RIGHT:
Right.x = event.getX();
Right.y = event.getY();
invalidate();
currentTouch = NONE;
return true;
case TOUCH_LEFT:
Left.x = event.getX();
Left.y = event.getY();
invalidate();
currentTouch = NONE;
return true;
}
return false;
All the post is in the article link
Below is a switch case logic for drawing on the surface, it doesn't draw properly. Not sure where am i going wrong. EDIT: class was removed as it was not helpful.
#Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (mThread.getSurfaceHolder()) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_DOWN:
currentDrawingPath = null;
currentDrawingPath = new DrawingPath();
currentDrawingPath.getPath().moveTo(eventX, eventY);
startX = eventX;
startY = eventY;
canvasPaths.add(currentDrawingPath);
//invalidate();
break;
case MotionEvent.ACTION_MOVE:
float dx = Math.abs(eventX - startX);
float dy = Math.abs(eventY - startY);
currentDrawingPath.getPath().quadTo(startX, startY,
(eventX + startX)/2, (eventY + startY)/2);
startX = eventX;
startY = eventY;
//currentDrawingPath.getPath().lineTo(startX, startY);
break;
}
return true;
Following is the code that fixed the issue,
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
currentDrawingPath.getPath().lineTo(event.getX(), event.getY());
break;
case MotionEvent.ACTION_DOWN:
currentDrawingPath = new DrawingPath();
currentDrawingPath.setPaintForPath();
// update the starting point of the new path
currentDrawingPath.getPath().moveTo(event.getX(), event.getY());
currentDrawingPath.getPath().lineTo(event.getX(), event.getY());
canvasPaths.add(currentDrawingPath);
break;
case MotionEvent.ACTION_MOVE:
currentDrawingPath.getPath().lineTo(event.getX(), event.getY());
break;
}
return true;