I'm currently processing movement on Android and I used MotionEvent.ACTION_MOVE.
I calculate currentx =(int) event.getX()/size and currenty=event.gety()/size, which gives me the integer base on the size of grid which I work on. Howevor, I want a way to find where the current y is changed while moving and decide to do something after that.
For example, if the size is equal to 10 then in x=150 and y=150 my currentx would be 15 and and currenty would be 15 but when currenty changed to something like 16 that means 150<event.get(y)<160. I want to know I'm in down direction etcetera.
public boolean onTouchEvent(MotionEvent event) {
//mGestureDetector.onTouchEvent(event);
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
initialX = event.getX();
initialY = event.getY();
Log.d(TAG, "Action was DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "Action was MOVE");
break;
case MotionEvent.ACTION_UP:
float finalX = event.getX();
float finalY = event.getY();
Log.d(TAG, "Action was UP");
if (initialX < finalX) {
Log.d(TAG, "Left to Right swipe performed");
}
if (initialX > finalX) {
Log.d(TAG, "Right to Left swipe performed");
}
if (initialY < finalY) {
Log.d(TAG, "Up to Down swipe performed");
}
if (initialY > finalY) {
Log.d(TAG, "Down to Up swipe performed");
}
break;
case MotionEvent.ACTION_CANCEL:
Log.d(TAG,"Action was CANCEL");
break;
case MotionEvent.ACTION_OUTSIDE:
Log.d(TAG, "Movement occurred outside bounds of current screen element");
break;
}
return super.onTouchEvent(event);
}
here is my code
private int getDirection(float startx, float starty,float endx ,float endy )
{
int direction=-1;
startx = (((int) startx / _size) *_size) ;
starty = (((int) starty / _size) * _size) ;
endx = (((int) endx / _size) * _size) ;
endy = (((int) endy / _size) * _size) ;
// Log.i("direction","startx:"+startx+"endx:"+endx+"starty: "+starty+"endy: "+endy+" ");
if (starty==endy)
{
direction= 0;
return direction;
}
if(startx==endx)
{
direction =1;
return direction;
}
if(Math.abs(startx-endx)==Math.abs(starty-endy))
{
direction =2;
return direction;
}
else
{
direction =-1;
return direction;
}
}
so i can find i'm in horizantal or vertical or non of these 2 cordinates but i need a way to compare the previous and current orientation while in action.move some thing like onDirectionChanggeListener
i can use action_up but i need it during move action.
Related
Basically I would like to draw lines on imageView when that image is zoomed.
The problem is that i dont know how to get right coordinates on touch event when Zoom In
Here is my code:
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: //first finger down only
savedMatrix.set(matrix);
if (draw) {
if (i == 1) {
startX = event.getX();
startY = event.getY();
i = 2;
} else if (i == 2) {
endX = event.getX();
endY = event.getY();
onDraw();
i = 3;
} else if (i == 3) {
startX = event.getX();
startY = event.getY();
onDraw();
i = 2;
}
} else {
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG");
mode = DRAG;
}
break;
case MotionEvent.ACTION_UP: //first finger lifted
case MotionEvent.ACTION_POINTER_UP: //second finger lifted
if (!draw) {
mode = NONE;
Log.d(TAG, "mode=NONE");
}
break;
case MotionEvent.ACTION_POINTER_DOWN: //second finger down
if (!draw) {
oldDist = spacing(event);
Log.d(TAG, "oldDist=" + oldDist);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
}
}
break;
case MotionEvent.ACTION_MOVE:
if (!draw) {
if (mode == DRAG) {
matrix.set(savedMatrix);
matrix.getValues(matrixValues);
matrixX = matrixValues[2];
matrixY = matrixValues[5];
width = matrixValues[0] * (view.getDrawable().getIntrinsicWidth());
height = matrixValues[4] * (view.getDrawable().getIntrinsicHeight());
dx = event.getX() - start.x;
dy = event.getY() - start.y;
//if image will go outside left bound
if (matrixX + dx > 0) {
dx = -matrixX;
}
//if image will go outside right bound
if (matrixX + dx + width < view.getWidth()) {
dx = view.getWidth() - matrixX - width;
}
//if image will go oustside top bound
if (matrixY + dy > 0) {
dy = -matrixY;
}
//if image will go outside bottom bound
if (matrixY + dy + height < view.getHeight()) {
dy = view.getHeight() - matrixY - height;
}
matrix.postTranslate(dx, dy);
}
break;
}
} //perform the transformation.
view.setImageMatrix(matrix);
return true; // indicate event was handled
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
private void sizeScreen() {
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
screenHeight = displaymetrics.heightPixels;
screenWidth = displaymetrics.widthPixels;
}
Here is method for zoom
#Override
public void onClick(View v) { // Parameter v stands for the imageView that was clicked.
matrix.set(savedMatrix);
float[] values = new float[9];
matrix.getValues(values);
switch (v.getId()) {
case (R.id.bt_zoom_in):
if (!draw) {
scale = scale + 0.1f;
if (scale > MAX_ZOOM) {
scale = MAX_ZOOM;
} else if (scale < MIN_ZOOM) {
scale = MIN_ZOOM;
}
}
break;
case R.id.bt_zoom_out:
if (!draw) {
scale = scale - 0.1f;
if (scale > MAX_ZOOM) {
scale = MAX_ZOOM;
} else if (scale < MIN_ZOOM) {
scale = MIN_ZOOM;
}
//matrix.setScale(scale, scale, mid.x, mid.y);
//imageView.setImageMatrix(matrix);
}
break;
case R.id.bt_draw:
if (draw) {
draw = false;
bt_draw.setText("Draw");
} else {
draw = true;
bt_draw.setText("Finish");
}
break;
}
matrix.setScale(scale, scale, mid.x, mid.y);
imageView.setImageMatrix(matrix);
}
Here is method for draw
public void onDraw() {
Bitmap lineABmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
Bitmap lineAMutBmp = lineABmp.copy(Bitmap.Config.ARGB_8888, true);
Bitmap copy = Bitmap.createBitmap(lineAMutBmp);
Canvas c = new Canvas(copy);
Paint pnt = new Paint();
pnt.setColor(Color.rgb(27, 163, 156));
pnt.setStrokeWidth(7);
c.drawLine(startX, startY, endX, endY, pnt);
imageView.setImageBitmap(copy);
}
}
Finally do it using this link I used the answer by Andres
public boolean onTouch(View v, MotionEvent event) {
...
float []m = new float[9];
matrix.getValues(m);
float transX = m[Matrix.MTRANS_X] * -1;
float transY = m[Matrix.MTRANS_Y] * -1;
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: //first finger down only
savedMatrix.set(matrix);
if (draw) {
if (i == 1) {
startX = Math.abs((event.getX() + transX) / scale);
startY = Math.abs((event.getY() + transY) / scale);
i = 2;
} else if (i == 2) {
endX = Math.abs((event.getX() + transX) / scale);
endY = Math.abs((event.getY() + transY) / scale);
onDraw();
i = 3;
} else if (i == 3) {
startX = Math.abs((event.getX() + transX) / scale);
startY = Math.abs((event.getY() + transY) / scale);
onDraw();
i = 2;
}
} else {
..
}
break;
case MotionEvent.ACTION_UP: //first finger lifted
case MotionEvent.ACTION_POINTER_UP: //second finger lifted
...
break;
case MotionEvent.ACTION_POINTER_DOWN: //second finger down
...
break;
case MotionEvent.ACTION_MOVE:
...
break;
}
} //perform the transformation.
view.setImageMatrix(matrix);
return true; // indicate event was handled
}
I'm doing a simple match-three game, similar to Bejeweled and I just want to move sprite objects by touching the sprite object and then move it one step in four directions like left, right, up and down. I do this by comparing the X and Y values on Down with the X and Y values on Move. It's working but it's far from perfect! It's so easy to get a wrong value if the movement isn't straight. My questions is: is there a way to improve this and make it better?
I have also looked at gesture, but this seems very complicated to use with a surfaceview that I have.
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("test","Down");
touchActionDownX = (int)event.getX();
touchActionDownY = (int)event.getY();
touchActionMoveStatus = true;
gameLoop.touchX = (int)event.getX();
gameLoop.touchY = (int)event.getY();
gameLoop.touchActionDown = true;
break;
case MotionEvent.ACTION_POINTER_UP:
touchActionMoveStatus = true;
break;
case MotionEvent.ACTION_MOVE:
//Log.i("test","Move");
gameLoop.touchActionMove = true;
if(touchActionMoveStatus) {
touchActionMoveX = (int)event.getX();
touchActionMoveY = (int)event.getY();
if(touchActionMoveX < touchActionDownX)
Log.i("test","Move Left");
else if(touchActionMoveX > touchActionDownX)
Log.i("test","Move Right");
else if(touchActionMoveY < touchActionDownY)
Log.i("test","Move Up");
else if(touchActionMoveY > touchActionDownY)
Log.i("test","Move Down");
touchActionMoveStatus = false; // Will be set to true when pointer is up
}
break;
}
// return false;
return true; // This gets the coordinates all the time
}
Try something like this:
#Override
public boolean onTouch(View v, MotionEvent event) {
//You may have to play with the value and make it density dependant.
int threshold = 10;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("test","Down");
touchActionDownX = (int)event.getX();
touchActionDownY = (int)event.getY();
touchActionMoveStatus = true;
gameLoop.touchX = (int)event.getX();
gameLoop.touchY = (int)event.getY();
gameLoop.touchActionDown = true;
break;
case MotionEvent.ACTION_POINTER_UP:
touchActionMoveStatus = false;
break;
case MotionEvent.ACTION_MOVE:
//Log.i("test","Move");
gameLoop.touchActionMove = true;
if(touchActionMoveStatus) {
touchActionMoveX = (int)event.getX();
touchActionMoveY = (int)event.getY();
if(touchActionMoveX < (touchActionDownX - threshold) && (touchActionMoveY > (touchActionDownY - threshold)) && (touchActionMoveY (touchActionDownY + threshold))){
Log.i("test","Move Left");//If the move left was greater than the threshold and not greater than the threshold up or down
touchActionMoveStatus = false;
}
else if(touchActionMoveX > (touchActionDownX + threshold) && (touchActionMoveY > (touchActionDownY - threshold)) && (touchActionMoveY < (touchActionDownY + threshold))){
Log.i("test","Move Right");//If the move right was greater than the threshold and not greater than the threshold up or
touchActionMoveStatus = false;
}
else if(touchActionMoveY < (touchActionDownY - threshold) && (touchActionMoveX > (touchActionDownX - threshold)) && (touchActionMoveX < (touchActionDownX + threshold))){
Log.i("test","Move Up");//If the move up was greater than the threshold and not greater than the threshold left or right
touchActionMoveStatus = false;
}
else if(touchActionMoveY > (touchActionDownY + threshold) && (touchActionMoveX > (touchActionDownX - threshold)) && (touchActionMoveX < (touchActionDownX + threshold))){
Log.i("test","Move Down");//If the move down was greater than the threshold and not greater than the threshold left or right
touchActionMoveStatus = false;
}
}
break;
}
// return false;
return true; // This gets the coordinates all the time
}
Or use a ratio:
#Override
public boolean onTouch(View v, MotionEvent event) {
//You may have to play with the value.
//A value of two means you require the user to move twice as
//far in the direction they intend to move than any perpendicular direction.
float threshold = 2.0;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("test","Down");
touchActionDownX = (int)event.getX();
touchActionDownY = (int)event.getY();
touchActionMoveStatus = true;
gameLoop.touchX = (int)event.getX();
gameLoop.touchY = (int)event.getY();
gameLoop.touchActionDown = true;
break;
case MotionEvent.ACTION_POINTER_UP:
touchActionMoveStatus = true;
break;
case MotionEvent.ACTION_MOVE:
//Log.i("test","Move");
gameLoop.touchActionMove = true;
if(touchActionMoveStatus) {
touchActionMoveX = (int)event.getX();
touchActionMoveY = (int)event.getY();
// I haven't tested this so you may have a few typos to correct.
float ratioLeftRight = Math.abs(touchActionMoveX - touchActionDownX)/Math.abs(touchActionMoveY - touchActionDownY)
float ratioUpDown = Math.abs(touchActionMoveY - touchActionDownY)/Math.abs(touchActionMoveX - touchActionDownX)
if(touchActionMoveX < touchActionDownX && ratioLeftRight > threshold){
Log.i("test","Move Left");
touchActionMoveStatus = false;
}
else if(touchActionMoveX > touchActionDownX && ratioLeftRight > threshold){
Log.i("test","Move Right");
touchActionMoveStatus = false;
}
else if(touchActionMoveY < touchActionDownY && ratioUpDown > threshold){
Log.i("test","Move Up");
touchActionMoveStatus = false;
}
else if(touchActionMoveY > touchActionDownY && ratioUpDown > threshold){
Log.i("test","Move Down");
touchActionMoveStatus = false;
}
}
break;
}
// return false;
return true; // This gets the coordinates all the time
}
I would choose the dimension with the LARGEST movement and completely ignore the other, for example if the move is x=10 and y=8 then only use the x dimension (i.e. left/right) and vice versa.
Also as noted by Larry McKenzie, using a threshold to ignore smaller movements is a good idea to prevent registering accidental movements that the user did not intend. Tweak the threshold value to someting that feels natural.
Here is some code using your example (only the ACTION_MOVE case):
case MotionEvent.ACTION_MOVE:
//Log.i("test","Move");
gameLoop.touchActionMove = true;
if(touchActionMoveStatus) {
touchActionMoveX = (int)event.getX();
touchActionMoveY = (int)event.getY();
// setup a threshold (below which no movement would occur)
int threshold = 5; /* tweak this as needed */
// first calculate the "delta" movement amounts
int xMove = touchActionMoveX - touchActionDownX;
int yMove = touchActionMoveY - touchActionDownY;
// now find the largest of the two (note that if they
// are equal, x is assumed largest)
if ( Math.abs( xMove ) >= Math.abs( yMove ) ) { /* X-Axis */
if ( xMove >= threshold )
Log.i("test","Move Right");
else if ( xMove <= -threshold )
Log.i("test","Move Left");
}
else { /* Y-Axis */
if ( yMove >= threshold )
Log.i("test","Move Down");
else if ( yMove <= -threshold )
Log.i("test","Move Up");
}
touchActionMoveStatus = false; // Will be set to true when pointer is up
}
}
break;
NOTE: As mentioned in some of the other answers, because multiple events with very small values can occur, it might be best to accumulate (i.e. sum up) the movements UNTIL the threshold is reached - you can use members for this that reset in ACTION_DOWN. Once the threshold is reached (in either dimension) THEN you can perform the checks for which direction.
Alternative Approach
Another way to go about it would be to detect the largest movement in the FIRST ACTION_MOVE event, and then lock all further movements to that dimension. For this you would need to add various state members - these would need to be updated in each state.
Here is a rough example (with only the state tracking):
// members
private boolean axisLock = false; /* Track When Lock is Required */
private boolean axisX = true; /* Axis to Lock (true) for X, (false) for Y */
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// set this state so that ACTION_MOVE knows a lock is required
axisLock = true;
break;
case MotionEvent.ACTION_UP:
// clear the state in case no move was made
axisLock = false;
case MotionEvent.ACTION_MOVE:
// now lock the axis if this is the first move event
if ( axisLock ) {
// this will set whether the locked axis is X (true) or Y (false)
axisX = event.getX() >= event.getY();
// reset the state (to keep the axis locked)
axisLock = false;
}
// at this point you only need to consider the movement for the locked axis
if ( axisX ) {
int movement = (int)event.getX(); /* Get Movement for Locked Axis */
// check for your movement conditions here
}
else {
int movement = (int)event.getY(); /* Get Movement for Locked Axis */
// check for your movement conditions here
}
break;
}
return true;
}
You could add many optimizations to this code, for now it just illustrates the basic idea.
larry had the right idea, i just want to put in a lil fix,
//put this in the wraping class
private static int THRESHOLD = 10;
private static int initX;
private static int initY;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initX = (int)event.getX();
initY = (int)event.getY();
break;
case MotionEvent.ACTION_POINTER_UP:
//you can add in some kind of "move back" animation for the item
break;
case MotionEvent.ACTION_MOVE:
if(((int)event.getY - initY) > THRESHOLD){
//move down
break;
}
if(((int)event.getY - initY) > -THRESHOLD){
//move up
break;
}
if(((int)event.getX - initX) > THRESHOLD){
//move right
break;
}
if(((int)event.getX - initX) < -THRESHOLD){
//move left
break;
}
break;
}
}
i didn't test this code, only free write it, but i hope you get my idea :)
I want to move the figure on list view item that contains phone number.
When I move figure from right to left, make a call. I'm failing to get that particoular item in list view to get the phone number and make a call.
My code is
#Override
arg1.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
float startX = 0;
float startY;
float endX;
float endY;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = (int) event.getX();
startY = (int) event.getY();
System.out.println("startX" + startX);
System.out.println("startY" + startY);
break;
case MotionEvent.ACTION_MOVE:
endX = event.getX();
endY = (int) event.getY();
System.out.println("endX" + endX);
System.out.println("endY" + endY);
float sub = endX - startX;
System.out.println("sub" + sub);
if ((endX - startX) < 100) {
arg0.setBackgroundColor(Color.GREEN);
}
if ((endX - startX) > 100) {
try {
TextView ph_tv = (TextView) arg0
.findViewById(R.id.textnum);
String Pho_no = ph_tv.getText().toString();
arg0.setBackgroundColor(Color.RED);
Intent intent = new Intent(
Intent.ACTION_CALL, Uri
.parse("tel:" + Pho_no));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
lv.setBackgroundColor(Color.BLACK);
} catch (ActivityNotFoundException e) {
Toast.makeText(
getApplicationContext(),
"Error in your phone call"
+ e.getMessage(),
Toast.LENGTH_LONG).show();
}
section(path_name, lv1);
}
break;
case MotionEvent.ACTION_UP:
endX = (int) event.getX();
endY = (int) event.getY();
}
return true;
}
});
float hX = Float.NaN, historicY = Float.NaN;
static final TRIGGER_DELTA = 50; // Number of pixels to travel till trigger
#Override public boolean onTouchEvent(MotionEvent e) {
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
hX = e.getX();
historicY = e.getY();
break;
case MotionEvent.ACTION_UP:
if (e.getX() - hX > -TRIGGER_DELTA) {
onSlideComplete(Direction.LEFT);
return true;
}
else if (e.getX() - hX > TRIGGER_DELTA) {
onSlideComplete(Direction.RIGHT);
return true;
} break;
default:
return super.onTouchEvent(e);
}
}
enum Direction {
LEFT, RIGHT;
}
interface OnSlideCompleteListener {
void onSlideComplete(Direction dir);
}
I'm developing an Android application and I would like to know if is possible to detect the direction of movement with one axis fixed. For example, I want put my phone on the table and detect the direction when I move it (left, right, up and down). The distance is not necessary, I just want to know the accurate direction.
Thanks!
my code is:
arg1.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
float startX = 0;
float startY;
float endX;
float endY;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = (int) event.getX();
startY = (int) event.getY();
System.out.println("startX" + startX);
System.out.println("startY" + startY);
break;
case MotionEvent.ACTION_MOVE:
endX = event.getX();
endY = (int) event.getY();
System.out.println("endX" + endX);
System.out.println("endY" + endY);
float sub = endX - startX;
System.out.println("sub" + sub);
if ((endX - startX) < 100) {
arg0.setBackgroundColor(Color.GREEN);
}
if ((endX - startX) > 100) {
try {
TextView ph_tv = (TextView) arg0
.findViewById(R.id.textnum);
String Pho_no = ph_tv.getText().toString();
arg0.setBackgroundColor(Color.RED);
Intent intent = new Intent(
Intent.ACTION_CALL, Uri
.parse("tel:" + Pho_no));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
lv.setBackgroundColor(Color.BLACK);
} catch (ActivityNotFoundException e) {
Toast.makeText(
getApplicationContext(),
"Error in your phone call"
+ e.getMessage(),
Toast.LENGTH_LONG).show();
}
section(path_name, lv1);
}
break;
case MotionEvent.ACTION_UP:
endX = (int) event.getX();
endY = (int) event.getY();
}
return true;
}
});
If you want to detect finger movement direction I think using onTouchListener for your case is not a good solution. I suggest you to use gesture listener
this is the example for left and right
class MyGestureDetector extends SimpleOnGestureListener {
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
// right to left swipe
if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(SelectFilterActivity.this, "Left Swipe", Toast.LENGTH_SHORT).show();
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(SelectFilterActivity.this, "Right Swipe", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
// nothing
}
return false;
}
}
you can do the same for up and down with calculating Y distance
If you have any other question about my answer or if you feel my answer isn't clear enough feel free to leave the question in the comment :)
I hope my answer helps you!
private final int mDragInterwell = 5;
private Point mStartPoint;
private final
#Override
public boolean onTouch(View arg0, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartPoint = new Point(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
final Point current = new Point(event.getX(), event.getY());
Log.d(getClass().getName(), decideMovement(current));
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
private String decideMovement(final Point point)
{
String direction = "invalid";
boolean changed = false;
if( ( mStartPoint.x - point.x ) > mDragInterwell )
{
direction = "left";
changed = true;
}else if( ( mStartPoint.x - point.x ) > -mDragInterwell )
{
changed = true;
direction = "right";
}else if( ( mStartPoint.y - point.y ) > mDragInterwell )
{
changed = true;
direction = "down";
}else if( ( mStartPoint.y - point.y ) > -mDragInterwell )
{
changed = true;
direction = "up";
}
if(changed)
{
mStartPoint = point;
}
return direction;
}
Hope this will help..
So i want to detect which direction the user moved his finger when touching the screen
Right now its working for 3 directions but the "up" movement does not get called.
This is my code:
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
// store the X value when the user's finger was pressed down
downXValue = event.getX();
downYValue = event.getY();
break;
}
case MotionEvent.ACTION_UP: {
// Get the X value when the user released his/her finger
float currentX = event.getX();
float currentY = event.getY();
//check if horizontal or vertical movement was bigger
if (Math.abs(downXValue - currentX) > Math.abs(downYValue)
- currentY) {
Log.e("motionevent", "x");
// going backwards: pushing stuff to the right
if (downXValue < currentX) {
Log.e("motionevent", "right");
}
// going forwards: pushing stuff to the left
if (downXValue > currentX) {
Log.e("motionevent", "left");
}
} else {
Log.e("motionevent", "y");
if (downYValue < currentY) {
Log.e("motionevent", "up");
}
if (downYValue > currentY) {
Log.e("motionevent", "down");
}
}
break;
}
}
return true;
}
Is there a Problem with checking for horizontal or vertical movement? because whenever i do an up movement, right or left gets called. down works fine.
You have error in your movement calculation. I have fixed it, its ok now.
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
// store the X value when the user's finger was pressed down
downXValue = event.getX();
downYValue = event.getY();
Log.v("", "= " + downYValue);
break;
}
case MotionEvent.ACTION_UP: {
// Get the X value when the user released his/her finger
float currentX = event.getX();
float currentY = event.getY();
// check if horizontal or vertical movement was bigger
if (Math.abs(downXValue - currentX) > Math.abs(downYValue
- currentY)) {
Log.v("", "x");
// going backwards: pushing stuff to the right
if (downXValue < currentX) {
Log.v("", "right");
}
// going forwards: pushing stuff to the left
if (downXValue > currentX) {
Log.v("", "left");
}
} else {
Log.v("", "y ");
if (downYValue < currentY) {
Log.v("", "down");
}
if (downYValue > currentY) {
Log.v("", "up");
}
}
break;
}
}
You can use GestureDetector.OnGestureListener interface which provides several methods to detect touch events: scroll, fling, etc.
Usage:
#Override
public boolean onTouchEvent(MotionEvent event) {
if (detector == null) {
detector = new GestureDetector(this);
}
return detector.onTouchEvent(event);
}
From now every events are recognized and passed to the specified method.