onTouchEvent onClick onLongClick calls
Asked Answered
B

6

12

In our application, we handle the events in a button to record data.

So initially when I use setOnLongClickListener() and setOnClickListener() together with the same button, it work fine for us.

That means it will call both this listener base on the click and LongClick of the button. Now when I tried to use setOnTouchListener() with the same button together with setOnLongClickListener() and setOnClickListener() then only OnTouch event is working, rest onclick and onLongclick event doesn't work.

Can anyone tell me why this happens and if possible explain me with an example.

The code I use:

Button btnAdd=new Button(this)

btnAdd.setOnLongClickListener(this);

btnAdd.setOnClickListener(this);

btnAdd.setOnTouchClickListener(this);

public void onClick(View v)
{
    //Statements;
}

public void onLongClick(View v)
{
    //Statements;
}

public boolean onTouch(View v, MotionEvent e) 
{
    switch (e.getAction())
    {
        case MotionEvent.ACTION_DOWN:
        {
            //store the X value when the user's finger was pressed down
            m_downXValue = e.getX();
            break;
        }   
        
        case MotionEvent.ACTION_UP:
        {
            //Get the X value when the user released his/her finger
            float currentX = e.getX();              
            //MotionEvent x=MotionEvent.obtain((long) m_downXValue,  SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 1, 1, 1, 1,0, 0, 0, 0, 0);
 
            // going forwards: pushing stuff to the left
            if (m_downXValue > currentX && currentX < 0)
            {                   
                ViewFlipper vf = (ViewFlipper) findViewById(R.id.flipview);
                vf.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_left));
                
               
                vf.showNext();
                               
            }
            
            // going backwards: pushing stuff to the right
            if (m_downXValue < currentX && currentX > 100)
            {                   
                ViewFlipper vf = (ViewFlipper) findViewById(R.id.flipview);                                     
                vf.setAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_right));
                
                
                vf.showPrevious();
                                  
            }   
            
            if (m_downXValue == currentX)
            {                   
                onClick(v);
            }    
         
            break;
        }
    }
    return true;
}
Broncobuster answered 7/9, 2011 at 12:5 Comment(4)
hey lukas can you please help me out to solve this problemBroncobuster
Do you consider the MotionEvent when calling onTouch?Ultramicroscope
i just edited the code for onTouch event..I found a clue to call onClick event..but how to call onLongClick event..please help meBroncobuster
hey dyonisos..have you go through the edited codeBroncobuster
U
25

According to the doc Handling UI Events,

onLongClick() - This returns a boolean to indicate whether you have consumed the event and it should not be carried further. That is, return true to indicate that you have handled the event and it should stop here; return false if you have not handled it and/or the event should continue to any other on-click listeners.

And above all about onTouch:

onTouch() - This returns a boolean to indicate whether your listener consumes this event. The important thing is that this event can have multiple actions that follow each other. So, if you return false when the down action event is received, you indicate that you have not consumed the event and are also not interested in subsequent actions from this event. Thus, you will not be called for any other actions within the event, such as a finger gesture, or the eventual up action event.

Indeed, depending on the event, you have to return the right value.

Upthrow answered 7/9, 2011 at 12:40 Comment(2)
can you show me with an example..i have used MotionEvent but by that i can call clickEvent but how to call LongClick event dont know..you can see my code above and please tell me what should i doBroncobuster
When you consume an event in onTouch and you don't want to call onClick or onLongClick, onTouch returns true. When no event is consumed in onTouch and you want to call onClick or onLongClick, onTouch returns false.Upthrow
B
4

You have to return false instead of true in OnTouch(View v,MotionEvent event) function so that other listeners on the control remains active.

Belew answered 7/6, 2012 at 9:10 Comment(0)
G
2

Seems like you have reference problem. Try to set click, long click and touch listener like this:

btnAdd.setOnClickListener(new Button.OnClickListener(){
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
    }
});

btnAdd.setOnLongClickListener(new Button.OnLongClickListener(){
    @Override
    public boolean onLongClick(View v) {
        // TODO Auto-generated method stub
        return false;
    }
});

btnAdd.setOnTouchListener(new Button.OnTouchListener(){
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        return false;
    }
});
Giacomo answered 7/9, 2011 at 12:14 Comment(2)
make sure your class is not implementing the touch listener..you can show the full class code..Giacomo
I think you tried it yourself..as per i know we have to use Motion Event to capture each event..and it work for Click event..but hoe to work it for Longclick..i dont know..Broncobuster
A
1

When you need both click and touch events on the same view, use a GestureDetector. It can detect long presses as well.

Auburn answered 9/10, 2013 at 13:27 Comment(0)
C
0

I'm not sure this is what you're trying to achieve, as you set the onTouchListener for the button - but if what you want to achieve is a swipeable activity (e.g swipe the screen and the content of the screen changes) you could try letting your activity extend the class posted below and then implement the next() and previous() methods with what ever actions you want.

import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.GestureDetector.SimpleOnGestureListener;

public abstract class SwipeActivity extends Activity {
    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    private GestureDetector gestureDetector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        gestureDetector = new GestureDetector( new SwipeDetector() );
    }

    private class SwipeDetector extends SimpleOnGestureListener {       
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {

            // Check movement along the Y-axis. If it exceeds SWIPE_MAX_OFF_PATH, then dismiss the swipe.
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                return false;

            // Swipe from right to left.
            // The swipe needs to exceed a certain distance (SWIPE_MIN_DISTANCE) and a certain velocity (SWIPE_THRESHOLD_VELOCITY).
            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                next();
                return true;
            }

            // Swipe from left to right.
            // The swipe needs to exceed a certain distance (SWIPE_MIN_DISTANCE) and a certain velocity (SWIPE_THRESHOLD_VELOCITY).
            if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                previous();
                return true;
            }

            return false;
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //TouchEvent dispatcher.
        if (gestureDetector != null) {
            if (gestureDetector.onTouchEvent(ev))
                //If the gestureDetector handles the event, a swipe has been executed and no more needs to be done.
                return true;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }

    protected abstract void previous();
    protected abstract void next();
}
Coppins answered 7/9, 2011 at 13:2 Comment(0)
C
0

Here is how i solved a synchronisation with ontouch and onlongclick

Hope every body can figure out after looking at this code. What happens is whenever a long press happens the touchlistener is set for a none listener and when the view is touched again the none listener sets the touchlistener of the view to its previous listener

LinearLayout.LayoutParams longpressLP = new LinearLayout.LayoutParams(100,100);
    LinearLayout longpress = new LinearLayout(this);
    longpress.setBackgroundColor(Color.GREEN);
    //any layout you want to add your view in
    mainlayout.addView(longpress,longpressLP);



    final View.OnTouchListener buttontouch=new View.OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {
                    if(event.getAction()==MotionEvent.ACTION_DOWN)
                Toast.makeText(getApplicationContext(), "Touched Down", Toast.LENGTH_SHORT).show();
            else
                Toast.makeText(getApplicationContext(), "Touched", Toast.LENGTH_SHORT).show();
            return false;//IMPORTANT
        }
    };
    final View.OnTouchListener buttontouchnone=new View.OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {

            if(event.getAction()==MotionEvent.ACTION_DOWN)//IMPORTANT
            {
                v.setOnTouchListener(buttontouch);//IMPORTANT
                v.dispatchTouchEvent(event);//IMPORTANT
                Toast.makeText(getApplicationContext(), "ChangedListener", Toast.LENGTH_SHORT).show();
            }
            return false;//IMPORTANT
        }
    };
            //set listeners
    longpress.setOnTouchListener(buttontouch);
    longpress.setOnLongClickListener(new View.OnLongClickListener() {

        public boolean onLongClick(View v) {
            // TODO Auto-generated method stub
            Toast.makeText(getApplicationContext(), "LongClick", Toast.LENGTH_SHORT).show();
            v.setOnTouchListener(buttontouchnone);//IMPORTANT
            return true;//IMPORTANT
        }
    });
Copula answered 3/6, 2012 at 12:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.