I don't know how WhatsApp works, but if you want to have an "infinite" sliding ViewPager you can return a large value in getCount()
and use modulo to get the correct image.
Something like:
public class ImageAdapter extends PagerAdapter {
List<Image> images;
public ImageAdapter(List<Image> images) {
this.images = images;
}
@Override
public int getCount() {
return images.size() * 100;
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
Image image = images.get(position % images.size());
// Instantiate your view
}
}
And when you set your ViewPager set the current item to a large value as well so you can actually scroll both ways
viewPager.setCurrentItem(images.size() * 50)
This will probably have some impact on performance as more views will have to be created.
Option 2
Another option is to add a ViewPager.OnPageChangeListener
that changes which item is the active one. You'll still have to return a larger value in getCount()
, but it's only three times the size of the list, so it won't be as drastic.
The idea is to scroll to the "same" item which takes you to the middle of the list so it feels like you're infinitely scrolling
In the adapter:
// For a list with 2 items, the list will look like:
// 0 1 0 1 0 1
@Override
public int getCount() {
return images.size() * 3;
}
// Set the first active item to be in the middle
// Here
// |
// 0 1 0 1 0 1
viewPager.setCurrentItem(images.size());
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
int currentPos;
@Override
public void onPageSelected(int position) {
currentPos = position;
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
// Here Go here Or here
// | | |
// 0 1 0 1 0 1
if (currentPos == images.size() - 1 || currentPos == adapter.getCount() - 1) {
// Scrolling with "false" removes the animation and instantly switches
// item, so you won't notice the scroll
viewPager.setCurrentItem(images.size() * 2 - 1, false);
} else if (currentPos == images.size() * 2 || currentPos == 0) {
// Or here Go here Here
// | | |
// 0 1 0 1 0 1
viewPager.setCurrentItem(images.size(), false);
}
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Not implemented
}
});
The problem with this solution is that it's not guaranteed that onPageScrollStateChanged
will be called with SCROLL_STATE_IDLE
since you might scroll to a new page before it reaches the idle state, which causes you to scroll past the item where it should switch. If you reach the end/start it will change items, but you will notice you can't scroll for a short time if you're scrolling fast enough.
Neither of these options are perfect, but hopefully it will give you an idea of what is possible.