2

When there is onclick, ontouch listeners attached to same ImageView, touch has priority over click.

I want an ImageView react to 2 different moves: swipe and single tap. How do I do this? right now, i do this:

swipe_area.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    x1 = event.getRawX();
                    break;
                case MotionEvent.ACTION_UP:
                    x2 = event.getRawX();
                    if (x1 < x2) {
                        switch (pencil_counter) {
                            case 1:
                                zad.setBackgroundResource(R.drawable.page13_zad6);
                                pered.setBackgroundResource(R.drawable.page13_pered6);
                                pencil_counter = 6;
                                break;
                            case 2:
                                zad.setBackgroundResource(R.drawable.page13_zad1);
                                pered.setBackgroundResource(R.drawable.page13_pered1);
                                pencil_counter = 1;
                                break;
xarlymg89
  • 2,552
  • 2
  • 27
  • 41
ERJAN
  • 23,696
  • 23
  • 72
  • 146

1 Answers1

2

You can filter single tap events through a GestureDetector like so:

private GestureDetectorCompat simpleGestureHandler = new GestureDetectorCompat(getContext(), new MySimpleGestureListener());

swipe_area.setOnTouchListener(new View.OnTouchListener()
{
    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        if(simpleGestureHandler.onTouchEvent(event))
        {
           //if true then a single tap
        }
        else
        {
           //calculate swipe action
        }
    }
}

class MySimpleGestureListener extends GestureDetector.SimpleOnGestureListener
{
    public boolean onSingleTapUp(MotionEvent e)
    {
        //single tap returns true so we know to register it over a swipe
        return true;
    }

    @Override
    public void onLongPress(MotionEvent event)
    {

    }

    @Override
    public boolean onDown(MotionEvent event)
    {

        return false;
    }

    @Override
    public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY)
    {

        return false;
    }

    @Override
    public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX, float distanceY)
    {


        return false;
    }
}
ripple182
  • 801
  • 1
  • 8
  • 13
  • can you explain a bit more - why we return for some methods false? – ERJAN Jul 22 '15 at 12:35
  • so our gesture listener only processes single tap events, all other touch events can be processed in the else statement (so we only process swipes if the gesture listener did not pick up a single tap event). – ripple182 Jul 22 '15 at 12:38
  • so i can still have 2 listeners attached to one view - ontouch & gesture? is this correct? – ERJAN Jul 22 '15 at 12:39
  • well the gesture listener is used inside the OnTouchListener implementation, so technically there's only the 1 touch listener on the view. – ripple182 Jul 22 '15 at 12:43