Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect swipe gesture when there's a ScrollView Android

I need to detect when there's a swipe on my App, I used this code and it works fine:

private float x1,x2;
static final int MIN_DISTANCE = 150;

and override onTouchEvent () method:

@Override
 public boolean onTouchEvent(MotionEvent event)
 {     
     switch(event.getAction())
     {
       case MotionEvent.ACTION_DOWN:
           x1 = event.getX();                         
       break;         
       case MotionEvent.ACTION_UP:
           x2 = event.getX();
           float deltaX = x2 - x1;
           if (Math.abs(deltaX) > MIN_DISTANCE)
           {
             Toast.makeText(this, "left2right swipe", Toast.LENGTH_SHORT).show ();
           }
           else
           {
               // consider as something else - a screen tap for example
           }                          
       break;   
     }           
     return super.onTouchEvent(event);       
 }

But if I have a scrollView on my Activity the code doesn't work anymore, How can I possibly fix this? Do I need to change completely the code i'm using?

EDIT: I tried to add the following method inside the if that detects the swipe gesture:

if (getParent() != null) {
                   getParent().requestDisallowInterceptTouchEvent(true);
               }

But I get an error on

requestDisallowInterceptTouchEvent

It says that I need to add cast to getParent()

like image 208
aisfdjjif Avatar asked Oct 31 '22 13:10

aisfdjjif


1 Answers

yes you can fix this :-) And there are 3 things you need to do:

  1. You need to add this method to your activity, this way you are making sure that your onTouchEvent function is always intercepting the event:

    @Override
    public boolean dispatchTouchEvent(MotionEvent event){
        this.onTouchEvent(event);
        return super.dispatchTouchEvent(event);
    }
    
  2. Add a global boolean variable as a flag. This is because while when there is a ListView, the super.dispatchTouchEvent lets the event consumed by the ListView. However, when there is not a ListView, the above code will dispatch the same swiping event to onTouchEvent twice (the second time is through the super.dispatchTouchEvent):

    boolean swapped = false;

  3. modify your onTouchEvent function to utilize the swapped flags:

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {  
     if(swapped){
         /*Make sure you don't swap twice,
    since the dispatchTouchEvent might dispatch your touch event to this function again!*/
         swapped = false;
         return super.onTouchEvent(event);
     }
     switch(event.getAction())
     {
       case MotionEvent.ACTION_DOWN:
           x1 = event.getX();                         
       break;         
       case MotionEvent.ACTION_UP:
           x2 = event.getX();
           float deltaX = x2 - x1;
           if (Math.abs(deltaX) > MIN_DISTANCE)
           {
             Toast.makeText(this, "left2right swipe", Toast.LENGTH_SHORT).show();
             //you already swapped, set flag swapped = true
             swapped = true;
           }
           else
           {
               // not swapping
           }                          
       break;   
     }           
     return super.onTouchEvent(event);       
    

    }

Note: don't add the code you mentioned in your post, and your MIN_DISTANCE is a bit too small, set it to 250 maybe.

like image 87
user3685578 Avatar answered Nov 13 '22 15:11

user3685578