Determine when touch down happens and then when it is released - android

I thought my code would work, but I guess not. I'm just trying to get it to read when the phone is touched. An animation will happen while its held. Then I would like it to determine when it is released so the animation will stop. My code looks like this with toasts as fillers until I get it working.
ImageView image = (ImageView)findViewById(R.id.pImage);
image.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN: {
Toast.makeText(PalsPage.this, "Is DOWN", Toast.LENGTH_SHORT).show();
break;
}
case MotionEvent.ACTION_UP: {
Toast.makeText(PalsPage.this, "Is UP", Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
Any help would be appreciated. Thanks

I think you are getting only the "Is DOWN" Toast.
The problem is in the return value.
You have to return truefor the code to work. otherwise the ACTION_UP event will not come to this view's listener.

you should return true so your image view keeps the events. i imagine your getting the first toast but not the second.

Related

Looking for a listener that differentiates between up and down events

I apologise for the somewhat noobish question.
I've tried googling it, searching this site and the android developer site, yet didn't manage to find an answer.
I'm looking for a listener that differentiates between up and down events. Currently I'm using OnTouchListener, but it gets triggered very fast, causing a noticable lag, even when I immediately return after an event that is not Down and Up.
I've also tried OnClickListener, but it seems to only get triggered when you lift your finger up, rather than have seperate events for down click and up click like I need.
Would appreciate some help,
Thanks!
YourBtn.setOnTouchListener(new View.OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event){
if(event.getAction() == MotionEvent.ACTION_UP){
//do stuff
}
else if(event.getAction() == MotionEvent.ACTION_DOWN){
//do stuff
}
else if(event.getAction() == MotionEvent.ACTION_CANCEL){
//do stuff
}
return true; //return false can be used it depends
}
});
P.S: it can be: a button, a textview, an imageview or any UI element
I strongly recommend to always add ACTION_CANCEL to avoid any misbehaviours or crashes
See this:
https://developer.android.com/training/graphics/opengl/touch.html
Override the following method on your activity, then you can treat each case, when the user touch the screen, and when he take of his finger.
#Override
public boolean onTouchEvent(MotionEvent e) {
// MotionEvent reports input details from the touch screen
// and other input controls. In this case, you are only
// interested in events where the touch position changed.
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
// do your stuff
break;
case MotionEvent.ACTION_UP:
// do your stuff
break;
}
return true;
}
You should look at GestureDetector to simplify your touch event handling.

onTouchListener in Android will detect touch on all parent view

I have
RelativeLayout
A---BIG IMAGE
B---MEDIUM IMAGE
C---SMALL IMAGE
The picture is looking like this
I have used below java code
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (v.getId()) {
// LEFT
case R.id.tblLOne:
System.out.println("IMG_L_A");
playBeep(TABLA_L_BIG);
changeLeftDrum();
break;
case R.id.tblLTwo:
System.out.println("IMG_L_B");
playBeep(TABLA_L_MID);
changeLeftDrum();
break;
case R.id.tblLThree:
System.out.println("IMG_L_C");
playBeep(TABLA_L_SMALL);
changeLeftDrum();
break;
return false;
}
return true;
}
Problem is that whenever I click on small (BLACK) Image
I got following output
IMG_L_A
IMG_L_B
IMG_L_C
Whenever I click on Middle Image I got
IMG_L_A
IMG_L_B
On OuterImage big image
IMG_L_A
Why I am getting it's all behind ImageView's OnTouch Method
It is working perfect with onClick but not with OnTouch
It's because the views are stacked on top of each other.
The important point here is to know the importance of the Boolean flag that you return from your onTouchListener. The boolean flag tells android if the event was consumed or not.
Suppose, you touch tblRthree, the case R.id.tblLThree executes, but then since you return false, it appears to android that the event was not consumed and this event bubbles up to the tblRTwo view which is just behind tblRthree view, which executes the same listener for the case R.id.tblLTwo but then again you return false so, it bubbles up to view tblROne and all three cases execute.
You should return true whenever you consume the event, and false when you don't.
onTouch method will be called in multiple events, all you need is to check whether it is MotionEvent.ACTION_DOWN or not.
So, it will look something like this:
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()!=MotionEvent.ACTION_DOWN)
{
return false;//we are not going to handle it
}
switch (v.getId()) {
// LEFT
case R.id.tblLOne:
System.out.println("IMG_L_A");
playBeep(TABLA_L_BIG);
changeLeftDrum();
break;
case R.id.tblLTwo:
System.out.println("IMG_L_B");
playBeep(TABLA_L_MID);
changeLeftDrum();
break;
case R.id.tblLThree:
System.out.println("IMG_L_C");
playBeep(TABLA_L_SMALL);
changeLeftDrum();
break;
}
return true;//we have handled it
}

Touching the screen while onTouch() is already being called

When I touch the screen and move my finger I do something (pullanimation1 and 2) and when I release the screen I do something else (fireanimation1 and 2). Sometimes, the user might touch the screen while pullAnimation or fireAnimation is running, I get errors as the animation then run several times. I would like to make sure the animations won't run more then once when the user touch again the screen.
NB: pullAnimation1 and 2, fireAnimation 1 and 2 are AnimationDrawable
Here is what I've done :
image2.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
boolean bool=false;
boolean bool2=true;
int action = arg1.getAction() & MotionEvent.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
if (bool2) {
startAnimation(pullAnimation1,pullAnimation2);
bool=true;
}
break;
case MotionEvent.ACTION_MOVE:
if (bool2==true){
Log.w("GAMEACTIVITY","move");
bool=true;
bool2=false;
}
break;
case MotionEvent.ACTION_UP:
startAnimation(fireAnimation1,fireAnimation2);
bool=false;
doPhotoTask();
bool2=false;
break;
}
return bool;
}
});
I think you should be able to use the hasStarted() and hasEnded() methods to determine if your animation is currently going. See the docs for more
Some if statement like this might work:
if((fireAnimation1.hasStarted() == false) || (fireAnimation1.hasEnded == true()){
startAnimation(fireAnimation1, fireAnimation2);
}
I imagine you may also need to use reset() after it is done playing in order or the methods to return proper values next time touch happens.
EDIT:
AnimationDrawable has an isRunning() method, which makes it even easier than View animations.
if(fireAnimation1.isRunning() == false){
startAnimation(fireAnimation1, fireAnimation2);
}

Android: Long touch on Button while MotionEvent.ACTION_MOVE

Ok... in my app i update the layout on MotionEvent.ACTION_DOWN and then i check the motion event coordinates to locate my buttons. I can show a toast when finger is released on different buttons. The problem is i need a long touch on my buttons to call another action without conflicting with the MotionEvent.ACTION_UP. Implemented a long click handler but since i don't 'click' its not working. Hope you guys understand my problem.
Whats the best way to get my app working as intended?
My class implements OnTouchListener, OnGestureListener
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
// UPDATE LAYOUT
break;
case MotionEvent.ACTION_UP:
// GET BUTTON X Y
if (x and y match the button location){
// DO ACTION
}else{
// DO NOTHING
}
// CHANGE LAYOUT TO INITIAL STATE
break;
case MotionEvent.ACTION_MOVE:
break;
}
return false;
mybutton.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// DO STUFF
return true;
}
});
}
just try to return false in your onTouch(...) method and use onLongClickListener(...) as usual

Handle OnTouch Event inside an Activity

Im Trying to handle an OnTouch Event inside an activity But I am unable to Handle MotionEvent.ACTION_UP Action. here is my code:
boardView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
showToastNotification("ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
showToastNotification("ACTION_UP");
break;
}
return false;
}
});
Why Is That?
Thanks in advance
Kobi
The "onTouch" event has to return "true" istead of "false".
Do you see the "ACTION_DOWN" toast? Is it just the "ACTION_UP" toast which does not show?
Could be (Guess) When ACTION_DOWN happens, the Toast appears and the Activity is not in control of ACTION_UP. Or.. as #C0deAttack said, it might be behind the scenes. Use ACTION_DOWN notification as Toast.short and ACTION_UP as Toast.long .. OR you could use LogCat.

Categories

Resources