Search code examples
androidonclickgesturetouch-event

onSingleTapUp - only for tapping on Buttons


I have two Buttons in my Linear Layout. I successfully override the onTouch of my Buttons so that when I fling over them something happens. I also want to be able to click on the Buttons so I override onSingleTapUp.

The problem is that onSingleTapUp works not only on my Buttons but for everywhere else on my screen too. So is there a way to make onSingleTapUp only refer to tapping of Buttons instead of tapping anywhere on the screen?

Attempt: I noticed MotionEvent has a boolean isButtonPressed(int button) so I tried the following but it crashed my application:

@Override
public boolean onSingleTapUp(MotionEvent ev) {
    if (ev.isButtonPressed(1))
        Log.d("button", "override - click event performed");
    return true;
}

Here is my full code:

class MainActivity:

public class MainActivity extends Activity {

    protected Button bttn1, bttn2;
    private GestureDetector mGestureDetector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mGestureDetector = new GestureDetector(this, new GestureListener());

        bttn1 = (Button) findViewById(R.id.bttn1);
        bttn2 = (Button) findViewById(R.id.bttn2);

        bttn1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.d("button1", "click event performed");
            }
        });

        bttn1.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                   if(mGestureDetector.onTouchEvent(event)) {

                        return true;
                    }
                    return false;

            }
        });

        bttn2.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.d("button2", "click event performed");
            }
        });

        bttn2.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                   if(mGestureDetector.onTouchEvent(event)) {

                        return true;
                    }
                    return false;

            }
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {

        boolean eventConsumed=mGestureDetector.onTouchEvent(event);
            if (eventConsumed)
            {
                return true;
            }
            else
                return false;
    }

}

class GestureListener:

package com.example.swipetest;

public class GestureListener extends GestureDetector.SimpleOnGestureListener{

    @Override
    public boolean onSingleTapUp(MotionEvent ev) {
        Log.d("button", "override - click event performed");
        return true;
    }

    @Override
    public boolean onDown(MotionEvent ev) {
      return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        Log.d("fling", "fling performed");
        return true;
    }
}

Solution

  • Maybe this will help you:

    public class MyTouchListener implements OnTouchListener{
    
    protected static final String TAG = "MyTouchListener";
    protected static final boolean D = true;
    
    public interface MyListener{
        public void onTouch();
        public void onClick();
    }
    
    private MyListener mListener;
    private GestureDetector mGestureDetector;
    
    
    private class MyClickListener extends SimpleOnGestureListener{
    
        @Override
        public boolean onDown(MotionEvent e) {
            if (D){
                Log.d(TAG, "onDown");
            }
            return true;
        }
    
        @Override
        public boolean onSingleTapUp(MotionEvent ev) {
            if (D){
                Log.d(TAG, "onSingleTapUp");
            }
            mListener.onClick();
            return true;
        }
    
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            if (D){
                Log.d(TAG, "onFling");
            }
            return true;
        }
    }
    
    public MyTouchListener(Context context, MyListener listener){
        mGestureDetector = new GestureDetector(context, new MyClickListener());
        mListener = listener;
    }
    
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (D){
            Log.d(TAG, "onTouch");
        }
        mListener.onTouch();
        mGestureDetector.onTouchEvent(event);
        return false;
    }
    
    }
    

    You could use it like this:

        Button b = (Button) findViewById(R.id.button);
    
        b.setOnTouchListener(new MyTouchListener(this, new MyListener() {
    
            @Override
            public void onTouch() {
                if (D){
                    Log.d(TAG, "onTouch");
                }
            }
    
            @Override
            public void onClick() {
                if (D){
                    Log.d(TAG, "onClick");
                }
            }
        }));