My face was like when I first saw this approach. Anyway, after some
research I finally found a correct way to implement this thing.

How to implement it correctly

The idea is quite simple. Let’s assume we have three pages A, B, C. The way
we want to put them in the ViewPager is like this:

[C][A][B][C][A]

We start with position 1.

When hit position 0 -> jump to position 3.

When hit position 4 -> jump to position 1.

Okay now let’s get to the code.

The Adapter

publicclassLoopingViewPagerAdapterextendsPagerAdapter{privateArrayList<Object>models;......@OverridepublicintgetCount(){// Since we want to put 2 additional pages at left & right,// the actual size will plus 2.returnmodels.size()==0?0:models.size()+2;}publicintgetRealCount(){returnmodels.size();}@OverridepublicObjectinstantiateItem(ViewGroupcontainer,intposition){intmodelPosition=mapPagerPositionToModelPosition(position);Objectmodel=models.get(modelPosition);return// create view using the model.}privateintmapPagerPositionToModelPosition(intpagerPosition){// Put last page model to the first position.if(pagerPosition==0){returngetRealCount()-1;}// Put first page model to the last position.if(pagerPosition==getRealCount()+1){return0;}returnpagerPosition-1;}}

The Listener

listener=newViewPager.OnPageChangeListener(){privateintjumpPosition=-1;@OverridepublicvoidonPageScrolled(intposition,floatpositionOffset,intpositionOffsetPixels){//We do nothing here.}@OverridepublicvoidonPageSelected(intposition){if(position==0){//prepare to jump to the last pagejumpPosition=adapter.getRealCount();//TODO: indicator.setActive(adapter.getRealCount() - 1)}elseif(position==adapter.getRealCount()+1){//prepare to jump to the first pagejumpPosition=1;//TODO: indicator.setActive(0)}else{//TODO: indicator.setActive(position - 1)}}@OverridepublicvoidonPageScrollStateChanged(intstate){//Let's wait for the animation to be completed then do the jump (if we do this in//onPageSelected(int position) scroll animation will be canceled).if(state==ViewPager.SCROLL_STATE_IDLE&&jumpPosition>=0){//Jump without animation so the user is not aware what happened.viewPager.setCurrentItem(jumpPosition,false);//Reset jump position.jumpPosition=-1;}}};

NOTE: Due to the way ViewPager is implemented, there’s no
way you can completely swipe to the next page. So when touch up, the ViewPager
will determine the next page according to your scroll position and animate to it.
The bad part about this is that, onPageSelected is hit when the animation
starts. So if you do the jump here you will cancel scroll animation and it will
look weird. The better solution is to wait for the animation to complete and
then do the jump.