Adding Fling Gesture to an image view - Android

79,941

Solution 1

Here's the simpliest working version of flinger I can think of. You can actually tie it to any component, not only ImageView.

public class MyActivity extends Activity {
    private void onCreate() {
        final GestureDetector gdt = new GestureDetector(new GestureListener());
        final ImageView imageView  = (ImageView) findViewById(R.id.image_view);
        imageView.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(final View view, final MotionEvent event) {
                gdt.onTouchEvent(event);
                return true;
            }
        });
    }               

    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;

    private class GestureListener extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                return false; // Right to left
            }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                return false; // Left to right
            }

            if(e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
                return false; // Bottom to top
            }  else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
                return false; // Top to bottom
            }
            return false;
        }
    }
}

No activity onClickListener though (if you don't need to catch any onclick actions) It captures not only horizontal, but vertical also (just delete vertical part if you don't need it), and horizontal swipes have priority as you can see. In places where method returns (nad where my comments are) just call your method or whatever :)

Solution 2

Try this

imageView.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (gestureDetector.onTouchEvent(event)) {
                return false;
            }
            return true;
        }
  });

Solution 3

imageView.setOnTouchListener(new View.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return !gestureDetector.onTouchEvent(event);
    }
});

Solution 4

some of the precondition

1) setonClick method

image.setOnClickListener(this);

2) set your gesture detection in onTouch()

image.setOnTouchListener(new OnTouchListener() {
    GestureDetector gestureDetector = new GestureDetector(new SwingGestureDetection((mContext),image,a));
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }
});

3) create SwingGestureDetection class and implement all method

@Override
public boolean onFling(MotionEvent start, MotionEvent finish, float arg2,float arg3) {
    if (start.getRawX() < finish.getRawX()) {
        System.out.println("next...swing");
    } else {
        System.out.println("previois...swing");
    }
}

4) pass your imageview in constructor

public SwingGestureDetection(Context con,ImageView image,int pos) {
    mContext = con;
    this.image = image;
    this.position = pos;
}

This is perfect work for me.if any query then put comment.

Solution 5

Try to read: http://illusionsandroid.blogspot.com/2011/05/adding-fling-gesture-listener-to-view.html

It allow you to separate your activity implementation from your custom listener. It is simply a refactoring of the solution reported by Alex Orlov

Share:
79,941
Ryan
Author by

Ryan

Updated on October 15, 2020

Comments

  • Ryan
    Ryan over 3 years

    Okay I have been referencing the code here: Fling gesture detection on grid layout

    but just can not get it to work. In my main activity I have a simple image defined. I want to detect a fling on the image. Here is my code below. The onclick method at the bottom is empty. Is it because of this? I left it blank because in the other code sample its not what I want. I just want a simple toast to pop up saying fling right or fling left.

    public class GestureRightLeft extends Activity implements OnClickListener  {
    
        ImageView peek;
    
        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;
        View.OnTouchListener gestureListener;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            peek =(ImageView) findViewById(R.id.peek);
            peek.setImageResource(R.drawable.bluestrip);
    
            gestureDetector = new GestureDetector(new MyGestureDetector());
            gestureListener = new View.OnTouchListener() {
                public boolean onTouch(View v, MotionEvent event) {
                    if (gestureDetector.onTouchEvent(event)) {
                        return true;
                    }
                    return false;
                }
            };
        }
    
        class MyGestureDetector extends SimpleOnGestureListener {
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                try {
                    if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                        return false;
                    // right to left swipe
                    if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                        Toast.makeText(GestureRightLeft.this, "Left Swipe", Toast.LENGTH_SHORT).show();
                    }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                        Toast.makeText(GestureRightLeft.this, "Right Swipe", Toast.LENGTH_SHORT).show();
                    }
                } catch (Exception e) {
                    // nothing
                }
                return false;
            }
        }
    
        @Override
        public void onClick(View v) {}
    }
    
  • Ganapathy C
    Ganapathy C about 13 years
    +1 thanks dude it worked for me.. i return true instead of false . now my problem solved
  • Richard
    Richard about 11 years
    Use final GestureDetector gdt = GestureDetector(this, new GestureListener()); instead, per developer.android.com/reference/android/view/…
  • Snicolas
    Snicolas about 11 years
    This is more like paging. A good flinging example can be found here : developer.android.com/training/custom-views/…
  • Ganapathy C
    Ganapathy C over 10 years
    @contactmeandroid inside if condition also i return true; it worked for me.
  • Srikanth Pai
    Srikanth Pai over 10 years
    @Ganapathy It worked but on swipe I wanted to drag the image and I was not able to do it
  • Ganapathy C
    Ganapathy C over 10 years
    drag and drop framework in android may help you.developer.android.com/guide/topics/ui/drag-drop.html
  • prodaea
    prodaea almost 9 years
    @Radu, read the link @Snicolas provided. You have to override onDown and return true.
  • Sipty
    Sipty almost 9 years
    The answer does not provide the fling logic, OP is looking for.
  • hgoebl
    hgoebl over 7 years
    I don't fully understand the code, but IMO this can't be correct, because onFling is returning false in all paths of execution.
  • Pedro Varela
    Pedro Varela almost 7 years
    Simplified return !mGestureDetector.onTouchEvent(motionEvent);