MotionEvents triggering no matter what in Android - java

I have this code for my MotionEvents in Android:
#Override
public boolean onTouchEvent(MotionEvent event){
int action = event.getActionMasked();
switch (action){
case MotionEvent.ACTION_UP:
mGameview.moveUp(30);
break;
case MotionEvent.ACTION_DOWN:
mGameview.moveDown(30);
break;
}
return true;
}
However, instead of these things only triggering when I drag my finger up/down, they both happen simultaneously no matter what I do in the app, for example when I tap, drag left and right.

Try to get action by:
int action = event.getAction() & MotionEvent.ACTION_MASK;

Related

Android OnTouch MotionEvent Actions

So I think I have a very simple issue but I can't seem to figure it out.
I have an ImageView and I am using it's setOnTouchListener method (OnTouch).
How can I differentiate between the ACTION_DOWN event and ACTION_MOVE event?
Even when I just click (touch) on the ImageView, ACTION_MOVE event gets called.
My goal is to open something(do anything) when the user clicks on it and move it when user holds it and moves it.
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
return true;
case MotionEvent.ACTION_UP:
return true;
case MotionEvent.ACTION_MOVE:
params.x = initialX + (int) (event.getRawX() - initialTouchX);
params.y = initialY + (int) (event.getRawY() - initialTouchY);
mWindowManager.updateViewLayout(mImgFloatingView, params);
// Log.d("Params", "X: " + params.x + ". Y: " + params.y + ".");
if(params.x == initialX && params.y == initialY) {
Toast.makeText(getBaseContext(), "Test", Toast.LENGTH_SHORT).show();
}
return true;
}
return false;
}
As others have said, ACTION_MOVE is called along with ACTION_DOWN because of the sensitivity of the device and the inherent unsensitivity of big fingers. This is known as touch slop. The results you want can be obtained by adjusting the thresholds for time and distance moved. Alternatively, you could use a gesture detector.
OnTouch MotionEvent Actions
Based on the title of the question, I came here looking for a quick reference for the onTouch MotionEvent actions. So here is a snippet copied from the documentation:
#Override
public boolean onTouchEvent(MotionEvent event){
int action = event.getActionMasked();
switch(action) {
case (MotionEvent.ACTION_DOWN) :
Log.d(DEBUG_TAG,"Action was DOWN");
return true;
case (MotionEvent.ACTION_MOVE) :
Log.d(DEBUG_TAG,"Action was MOVE");
return true;
case (MotionEvent.ACTION_UP) :
Log.d(DEBUG_TAG,"Action was UP");
return true;
case (MotionEvent.ACTION_CANCEL) :
Log.d(DEBUG_TAG,"Action was CANCEL");
return true;
case (MotionEvent.ACTION_OUTSIDE) :
Log.d(DEBUG_TAG,"Movement occurred outside bounds " +
"of current screen element");
return true;
default :
return super.onTouchEvent(event);
}
}
Notes:
The above code could be used in an activity or a subclassed view. If subclassing a view is not desired, then the same motion events can be tracked by adding an OnTouchListener to the view. (example also taken from the documentation)
View myView = findViewById(R.id.my_view);
myView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// ... Respond to touch events
return true;
}
});
Difference between getAction() and getActionMasked()
Returning true means that future events will still be processed. So if you returned false for ACTION_DOWN then all other events (like move or up) would be ignored.
Further reading
Using Touch Gestures: This is a series of official lessons in the documentation. It is an essential read for understanding how to correctly handle touch events and gestures.
What is happening is that View.OnTouchListener will send you ALL events. If you tap and move by only 1 pixel, it'll be registered as a ACTION_MOVE.
You will need to implement some logic to determine a 'hold' action - waiting 100ms or something similar - after which a 'drag' action can proceed. Before that time, it should just be a 'click' action.

Scroll view does not scroll on first touch

I have the following code, all I want is to detect touch on a edit text and scroll the scroll view:
View.OnTouchListener buttonFocus = new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("TOuch");
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
System.out.println("TOuch down");
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
break;
case MotionEvent.ACTION_UP:
System.out.println("TOuch up");
((ScrollView) findViewById(R.id.m_scroll)).fullScroll(View.FOCUS_DOWN);
v.performClick();
break;
default:
break;
}
return false;
}
};
While as the keypad pops up at the start of activity the scroll does not occur, it only scroll when I touch the view for the second time. Am I doing something wrong here? Will implementing a thread help?
Returning true in that last line of yours might solve your problem.
Returning false means that the onTouch has been used completely and won't entertain any further touch events

Finger touch/press/drag

I know that there are listeners for finger touch etc.. but I wonder how I can decet a finger drag up/down/left/right.
Is there any kind of listener for that?or it's some math involved.
Use this
#Override
public boolean onTouchEvent(MotionEvent e) {
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
Try taking a look at the Android Developer Resources sometime.

Why is my onTouchListener called for neighbour views?

In my application I want to add a simple animation to buttons and other views acting as buttons.
To do this I set a custom onTouchListener to all views and call startAnimation on them.
My onTouch method looks like this:
public boolean onTouch(View v, MotionEvent event) {
// Only show animation when enabled.
if (v.isEnabled()) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
v.startAnimation(shrink);
break;
case MotionEvent.ACTION_UP:
v.startAnimation(grow);
break;
}
}
return v.onTouchEvent(event);
}
This works ok as the views are resized to a smaller size while the user presses the button and returns to the original size when the user releases the finger.
However for some reason other buttons that lie near the touched button also get the UP event so they get a small animation flicker as well.
Why is this, and more importantly, how do I prevent this annoying behaviour?
Edit: Just to be clear. The neighbour views are also registered to the same listener instance, but they are not touched by my finger.
The view to wich you have registered listener then should only get notified then also use following approach.
You can explicitly check what is id of View and then only start animation.
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.desired_view_id) {
// Only show animation when enabled.
if (v.isEnabled()) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
v.startAnimation(shrink);
break;
case MotionEvent.ACTION_UP:
v.startAnimation(grow);
break;
}
}
}
return v.onTouchEvent(event);
}
The problem was using the same Animation instance on several views. Creating seperate instances for each view fixed the problem.

How to handle touch or press down events in Android?

Alright so i have 4 image views..
How can i control what happens when they are pressed down and up
So say like:
one of the images is press down a textview gets changed to 1 but when they let go of that one the text will change back to 0?
You need to use an OnTouchListener and have it listen for TouchEvents on your Views.
For Example:
MyTouchListener l = new MyTouchListener();
view.setOnTouchListener(l);
Here is an example of what MyTouchListener could look like:
class MyOnTouchListener implements OnTouchListener {
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
// touch down code
break;
case MotionEvent.ACTION_MOVE:
// touch move code
break;
case MotionEvent.ACTION_UP:
// touch up code
break;
}
return true;
}
}

Categories