package me.qixingchen.mdbilibili.widget;
import android.os.Parcelable;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by qixingchen on 15/12/4.
* pager无限循环
*/
public class LoopPagerAdapter extends PagerAdapter {
private PagerAdapter mAdapter;
private SparseArray<ToDestroy> mToDestroy = new SparseArray<ToDestroy>();
private boolean mBoundaryCaching;
LoopPagerAdapter(PagerAdapter adapter) {
this.mAdapter = adapter;
}
void setBoundaryCaching(boolean flag) {
mBoundaryCaching = flag;
}
@Override
public void notifyDataSetChanged() {
mToDestroy = new SparseArray<ToDestroy>();
super.notifyDataSetChanged();
}
int toRealPosition(int position) {
int realCount = getRealCount();
if (realCount == 0)
return 0;
int realPosition = (position - 1) % realCount;
if (realPosition < 0)
realPosition += realCount;
return realPosition;
}
public int toInnerPosition(int realPosition) {
int position = (realPosition + 1);
return position;
}
private int getRealFirstPosition() {
return 1;
}
private int getRealLastPosition() {
return getRealFirstPosition() + getRealCount() - 1;
}
@Override
public int getCount() {
return mAdapter.getCount() + 2;
}
public int getRealCount() {
return mAdapter.getCount();
}
public PagerAdapter getRealAdapter() {
return mAdapter;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
int realPosition = (mAdapter instanceof FragmentPagerAdapter || mAdapter instanceof FragmentStatePagerAdapter)
? position
: toRealPosition(position);
if (mBoundaryCaching) {
ToDestroy toDestroy = mToDestroy.get(position);
if (toDestroy != null) {
mToDestroy.remove(position);
return toDestroy.object;
}
}
return mAdapter.instantiateItem(container, realPosition);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
int realFirst = getRealFirstPosition();
int realLast = getRealLastPosition();
int realPosition = (mAdapter instanceof FragmentPagerAdapter || mAdapter instanceof FragmentStatePagerAdapter)
? position
: toRealPosition(position);
if (mBoundaryCaching && (position == realFirst || position == realLast)) {
mToDestroy.put(position, new ToDestroy(container, realPosition,
object));
} else {
mAdapter.destroyItem(container, realPosition, object);
}
}
/*
* Delegate rest of methods directly to the inner adapter.
*/
@Override
public void finishUpdate(ViewGroup container) {
mAdapter.finishUpdate(container);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return mAdapter.isViewFromObject(view, object);
}
@Override
public void restoreState(Parcelable bundle, ClassLoader classLoader) {
mAdapter.restoreState(bundle, classLoader);
}
@Override
public Parcelable saveState() {
return mAdapter.saveState();
}
@Override
public void startUpdate(ViewGroup container) {
mAdapter.startUpdate(container);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
mAdapter.setPrimaryItem(container, position, object);
}
/*
* End delegation
*/
/**
* Container class for caching the boundary views
*/
static class ToDestroy {
ViewGroup container;
int position;
Object object;
public ToDestroy(ViewGroup container, int position, Object object) {
this.container = container;
this.position = position;
this.object = object;
}
}
}