Android ACTION_UP even never called - android

I'm trying to make a small android Jump and Run game but my problem is that i can't configure the event ACTION_UP right. Here my Code:
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("OTE", "down");
touchDownTrue = true;
break;
case MotionEvent.ACTION_UP:
Log.d("OTE", "UP");
touchDownTrue = false;
break;
}
}
the case MotionEvent.ACTION_UP is never called and i don't know why, the same happens if i use ACTION_CANCEL

After I insert return super.onTouchEvent(event); at the end of the method (onTouchEvent must return a value) your code works for me, when I put it in a blank main activity.
You should probably return true instead of breaking in those cases because you are responding to the event.

Related

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 Distinguishing Between Click and Drag dispatchTouchEvent

I am currently using dispatchTouchEvent to grab touch events, is there an easy way to distinguish between a click and a "drag" stylt gesture?
DispatchTouchEvent is called with a MotionEvent parameter. Method getAction within MotionEvent can return
ACTION_DOWN
ACTION_MOVE
ACTION_UP
ACTION_CANCEL
Then set on ACTION_DOWN flag isClick. If there is ACTION_MOVE clear isClick flag.
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
isClick = true;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (isClick) {
//TODO Click action
}
break;
case MotionEvent.ACTION_MOVE:
isClick = false;
break;
default:
break;
}
return true;
}
set up a threshold limit.When you move the pointer within a small range make it recognized as a click or else a movement

Multitouch issue: when pressing two buttons at the same time, it detects as if I touched only one with my fingers, why?

So I have two buttons and would like to press both at the same time. If I press the first it logs a "C" (as a piano note), the other logs a D.
So far:
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getActionMasked();
switch (event.getAction() & MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
switch (v.getId()) {
case R.id.cnotebutton:
Log.i("C", "C1");
return true;
case R.id.c2notebutton:
Log.i("D", "D1");
return true;
default:
}
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
switch (v.getId()) {
case R.id.cnotebutton:
Log.i("C", "C2");
return true;
case R.id.c2notebutton:
Log.i("D", "D2");
return true;
default:
}
break;
case MotionEvent.ACTION_MOVE:
break;
default:
}
return true;
}
I Log C1 and C2 to distinguish the cases, but every time I press the buttons I get only C1,C2 or D1,D2 as if I touched the same buttons with both of my fingers. I should get C1,D2 or D1,C2 depending on which finger pointed first. Any suggestions?
Anyway I havent found a piano sample project yet, but that would definetly help me, if this is not going to work or my approach is totally wrong. Is there any?
Thanks in advance!
I think public boolean onInterceptTouchEvent (MotionEvent ev)is what you are looking for. Take a look at this.

GridView problems with touchlisteners

I'm trying to create a custom GridView but i'm having troubles with the touch listeners.
What i want to do:
Create a GridView with custom Views.
Longpress on an item so it becomes 'editable'.
Drag the view horizontal or vertical to move it's position in the GridView.
Here's where i'm having trouble:
I'm implementing GestureDetector.OnGestureListener for the longpress functions, because for some reason using the gridview.setOnItemLongClickListener() isn't working when overriding the onTouchEvent() of the GridView itself (Which i need for the dragging part). So everything is fine at this point. Now i only need to know when the longpress is finished. So i though: "Well this shouldn't be hard." I couldn't have be more wrong. I've fiddled around for quite some time with this and it looks like using different touch events isn't helping me :/
When stepping through the onTouchEvent() i noticed that only 1 action is given: MotionEvent.ACTION_DOWN. So what am i doing wrong? i need the MotionEvent.ACTION_UP...
Found the culprit:
i was doing something like this
#Override
public boolean onTouchEvent(MotionEvent event) {
// Give everything to the gesture detector
boolean retValue = gestureDetector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE :
onMove();
break;
case MotionEvent.ACTION_UP :
onUp();
break;
case MotionEvent.ACTION_CANCEL:
onCancel();
break;
}
return retValue;
}
i think retValue was always returning false so no other events were triggered.
this fixed the issue:
#Override
public boolean onTouchEvent(MotionEvent event) {
// Give everything to the gesture detector
gestureDetector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE :
onMove();
break;
case MotionEvent.ACTION_UP :
onUp();
break;
case MotionEvent.ACTION_CANCEL:
onCancel();
break;
}
return true;
}

Categories

Resources