Created
October 17, 2017 05:32
-
-
Save hitesh-dhamshaniya/82b861d50a0f241e0093dbe63d4f41ac to your computer and use it in GitHub Desktop.
Endless View Pager for Android
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.infiteviewpager; | |
import android.database.DataSetObserver; | |
import android.os.Parcelable; | |
import android.support.v4.view.PagerAdapter; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import com.devdigital.providence.utils.Logger; | |
public class InfinitePagerAdapter extends PagerAdapter { | |
private static final String TAG = "InfinitePagerAdapter"; | |
private static final boolean DEBUG = false; | |
private PagerAdapter adapter; | |
public InfinitePagerAdapter(PagerAdapter adapter) { | |
this.adapter = adapter; | |
} | |
@Override | |
public int getCount() { | |
if (getRealCount() == 0) { | |
return 0; | |
} | |
// warning: scrolling to very high values (1,000,000+) results in | |
// strange drawing behaviour | |
return Integer.MAX_VALUE; | |
} | |
/** | |
* @return the {@link #getCount()} result of the wrapped adapter | |
*/ | |
public int getRealCount() { | |
return adapter.getCount(); | |
} | |
@Override | |
public Object instantiateItem(ViewGroup container, int position) { | |
int virtualPosition = position % getRealCount(); | |
debug("instantiateItem: real position: " + position); | |
debug("instantiateItem: virtual position: " + virtualPosition); | |
// only expose virtual position to the inner adapter | |
return adapter.instantiateItem(container, virtualPosition); | |
} | |
@Override | |
public void destroyItem(ViewGroup container, int position, Object object) { | |
int virtualPosition = position % getRealCount(); | |
debug("destroyItem: real position: " + position); | |
debug("destroyItem: virtual position: " + virtualPosition); | |
// only expose virtual position to the inner adapter | |
adapter.destroyItem(container, virtualPosition, object); | |
} | |
/* | |
* Delegate rest of methods directly to the inner adapter. | |
*/ | |
@Override | |
public void finishUpdate(ViewGroup container) { | |
adapter.finishUpdate(container); | |
} | |
@Override | |
public boolean isViewFromObject(View view, Object object) { | |
return adapter.isViewFromObject(view, object); | |
} | |
@Override | |
public void restoreState(Parcelable bundle, ClassLoader classLoader) { | |
adapter.restoreState(bundle, classLoader); | |
} | |
@Override | |
public Parcelable saveState() { | |
return adapter.saveState(); | |
} | |
@Override | |
public void startUpdate(ViewGroup container) { | |
adapter.startUpdate(container); | |
} | |
@Override | |
public CharSequence getPageTitle(int position) { | |
int virtualPosition = position % getRealCount(); | |
return adapter.getPageTitle(virtualPosition); | |
} | |
@Override | |
public float getPageWidth(int position) { | |
return adapter.getPageWidth(position); | |
} | |
@Override | |
public void setPrimaryItem(ViewGroup container, int position, Object object) { | |
adapter.setPrimaryItem(container, position, object); | |
} | |
@Override | |
public void unregisterDataSetObserver(DataSetObserver observer) { | |
adapter.unregisterDataSetObserver(observer); | |
} | |
@Override | |
public void registerDataSetObserver(DataSetObserver observer) { | |
adapter.registerDataSetObserver(observer); | |
} | |
@Override | |
public void notifyDataSetChanged() { | |
adapter.notifyDataSetChanged(); | |
} | |
@Override | |
public int getItemPosition(Object object) { | |
return adapter.getItemPosition(object); | |
} | |
/* | |
* End delegation | |
*/ | |
private void debug(String message) { | |
if (DEBUG) { | |
Logger.debug(TAG, message); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.infiteviewpager; | |
import android.content.Context; | |
import android.support.v4.view.PagerAdapter; | |
import android.util.AttributeSet; | |
import com.devdigital.providence.components.NonSwipeableViewPager; | |
public class InfiniteViewPager extends NonSwipeableViewPager { | |
public InfiniteViewPager(Context context) { | |
super(context); | |
} | |
public InfiniteViewPager(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
} | |
@Override | |
public void setAdapter(PagerAdapter adapter) { | |
super.setAdapter(adapter); | |
// offset first element so that we can scroll to the left | |
setCurrentItem(0); | |
} | |
@Override | |
public void setCurrentItem(int item) { | |
// offset the current item to ensure there is space to scroll | |
setCurrentItem(item, false); | |
} | |
@Override | |
public void setCurrentItem(int item, boolean smoothScroll) { | |
if (getAdapter() != null) { | |
if (getAdapter().getCount() == 0) { | |
super.setCurrentItem(item, smoothScroll); | |
return; | |
} | |
item = getOffsetAmount() + (item % getAdapter().getCount()); | |
super.setCurrentItem(item, smoothScroll); | |
} | |
} | |
@Override | |
public int getCurrentItem() { | |
if (getAdapter().getCount() == 0) { | |
return super.getCurrentItem(); | |
} | |
int position = super.getCurrentItem(); | |
if (getAdapter() instanceof InfinitePagerAdapter) { | |
InfinitePagerAdapter infAdapter = (InfinitePagerAdapter) getAdapter(); | |
// Return the actual item position in the data backing InfinitePagerAdapter | |
return (position % infAdapter.getRealCount()); | |
} else { | |
return super.getCurrentItem(); | |
} | |
} | |
private int getOffsetAmount() { | |
if (getAdapter().getCount() == 0) { | |
return 0; | |
} | |
if (getAdapter() instanceof InfinitePagerAdapter) { | |
InfinitePagerAdapter infAdapter = (InfinitePagerAdapter) getAdapter(); | |
// allow for 100 back cycles from the beginning | |
// should be enough to create an illusion of infinity | |
// warning: scrolling to very high values (1,000,000+) results in | |
// strange drawing behaviour | |
return infAdapter.getRealCount() * 100; | |
} else { | |
return 0; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
public class InfiniteViewPager extends NonSwipeableViewPager{} just extend ViewPager also worked.