sandalone
sandalone

Reputation: 41749

How to create smooth swipe as in ViewPager?

I need to code swipe back in an app. However, using ViewPager would not fit into the design so I have to code swipe logic.

I have done it dozens of times in the past via Gestures, but the swipe is never as smooth as in ViewPager for example. It's not reliable. Sometimes it works fine, but often swipe is not recognized so I had to swipe again. Another issue was that swipe action would call "pull to refresh" indicator so swipe would not be activated again.

Is there any library which has perfect swipe logic? If not, I will post the swipe logic I usually use so you can tell me its flaws.

Upvotes: 0

Views: 2326

Answers (2)

nomanr
nomanr

Reputation: 3775

This is my onSwipeTouchListener class.

public class OnSwipeTouchListener implements View.OnTouchListener {

private GestureDetector gestureDetector;

public OnSwipeTouchListener(Context c) {
    gestureDetector = new GestureDetector(c, new GestureListener());
}

public boolean onTouch(final View view, final MotionEvent motionEvent) {
    return gestureDetector.onTouchEvent(motionEvent);
}

private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

    private static final int SWIPE_THRESHOLD = 10;
    private static final int SWIPE_VELOCITY_THRESHOLD = 10;

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

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        onClick();
        return super.onSingleTapUp(e);
    }

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        onDoubleClick();
        return super.onDoubleTap(e);
    }

    @Override
    public void onLongPress(MotionEvent e) {
        onLongClick();
        super.onLongPress(e);
    }

    // Determines the fling velocity and then fires the appropriate swipe event accordingly
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        boolean result = false;
        try {
            float diffY = e2.getY() - e1.getY();
            float diffX = e2.getX() - e1.getX();
            if (Math.abs(diffX) > Math.abs(diffY)) {
                if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffX > 0) {
                        onSwipeRight();
                    } else {
                        onSwipeLeft();
                    }
                }
            } else {
                if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        onSwipeDown();
                    } else {
                        onSwipeUp();
                    }
                }
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return result;
    }
}

public void onSwipeRight() {
}

public void onSwipeLeft() {
}

public void onSwipeUp() {
}

public void onSwipeDown() {
}

public void onClick() {

}

public void onDoubleClick() {

}

public void onLongClick() {

}

}

This is how you can use it.

mainView.setOnTouchListener(new OnSwipeTouchListener(getActivity()) {

        @Override
        public void onSwipeUp() {
               // Do Stuff here
        }

        @Override
        public void onClick() {
                // Do Stuff here

        }
    });

It is very smooth. I tried many other examples but this was the best one. Also you can set threshold for swipe gesture. All you need to do is change these variables.

private static final int SWIPE_THRESHOLD = 10;
private static final int SWIPE_VELOCITY_THRESHOLD = 10;

It can detect LeftSwipe,RightSwipe,UpSwipe,DownSwipe,OnClick,OnDoubleClick and OnLongClick.

I used this class for changing fragments on UpSwipe and DownSwipe gestures.

Upvotes: 5

David
David

Reputation: 1770

Use the PageStrip. It's very smooth and very good.

http://codetheory.in/android-pagertabstrip-pagertitlestrip-viewpager/

Upvotes: -1

Related Questions