EDIT: I have a much simpler implementation with ViewPager, and the github project has been updated. See post here.
I have a GrideView of images, which enlarges to full screen when you tap on any image. When I showed it to my friend he swiped to get to the next image, but that did not do anything because I was just using a plain old ImageView. I looked around for a standard widget to do that, and couldn't find any. So I unwillingly rolled my own solution: http://github.com/chiuki/android-swipe-image-viewer.
I show the image in an ImageSwitcher. It contains two views, one displays the current image, and the other one holds the image to swap in. I lifted the gesture listener code from the Android Gallery app:
private class SwipeListener extends SimpleOnGestureListener {
private static final int SWIPE_MIN_DISTANCE = 75;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
@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) {
moveNextOrPrevious(1);
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
moveNextOrPrevious(-1);
}
} catch (Exception e) {
// nothing
}
return false;
}
}
moveNextOrPrevious() swaps in the previous or next image with the appropriate animation:
private void moveNextOrPrevious(int delta) {
int nextImagePos = mCurrentPosition + delta;
if (nextImagePos < 0) {
mOverscrollLeft.setVisibility(View.VISIBLE);
mOverscrollLeft.startAnimation(mOverscrollLeftFadeOut);
return;
}
if (nextImagePos >= mImages.length) {
mOverscrollRight.setVisibility(View.VISIBLE);
mOverscrollRight.startAnimation(mOverscrollRightFadeOut);
return;
}
mImageSwitcher.setInAnimation(
delta > 0 ? mSlideInRight : mSlideInLeft);
mImageSwitcher.setOutAnimation(
delta > 0 ? mSlideOutLeft : mSlideOutRight);
mCurrentPosition = nextImagePos;
mImageSwitcher.setImageResource(mImages[mCurrentPosition]);
}
Notice how I show an overscroll grow when the user reaches the start or the end of the list of images. I make it visible immediately, and then use an animation to fade it away.
Right now all the logic is in MainActivity. I thought about encapsulating the viewer code into a custom view and bundling it into a jar file, but I am not sure how many people will find it useful, so laziness got the better of me. If you want to get a jar file to reuse this code, please let me know.
Until then, here is the source code: http://github.com/chiuki/android-swipe-image-viewer.