继承同一个父类 PagerAdapter
public abstract class FragmentStatePagerAdapter extends PagerAdapter { | |
private static final String TAG = "FragmentStatePagerAdapter"; | |
private static final boolean DEBUG = false; | |
private final FragmentManager mFragmentManager; | |
private FragmentTransaction mCurTransaction = null; | |
private ArrayList<Fragment.SavedState> mSavedState = new ArrayList<Fragment.SavedState>(); | |
private ArrayList<Fragment> mFragments = new ArrayList<Fragment>(); | |
private Fragment mCurrentPrimaryItem = null; | |
public FragmentStatePagerAdapter(FragmentManager fm) { | |
mFragmentManager = fm; | |
} | |
/** | |
* Return the Fragment associated with a specified position. | |
*/ | |
public abstract Fragment getItem(int position); | |
@Override | |
public void startUpdate(ViewGroup container) { | |
if (container.getId() == View.NO_ID) { | |
throw new IllegalStateException("ViewPager with adapter " + this | |
+ " requires a view id"); | |
} | |
} | |
@Override | |
public Object instantiateItem(ViewGroup container, int position) { | |
// If we already have this item instantiated, there is nothing | |
// to do. This can happen when we are restoring the entire pager | |
// from its saved state, where the fragment manager has already | |
// taken care of restoring the fragments we previously had instantiated. | |
if (mFragments.size() > position) { | |
Fragment f = mFragments.get(position); | |
if (f != null) { | |
return f; | |
} | |
} | |
if (mCurTransaction == null) { | |
mCurTransaction = mFragmentManager.beginTransaction(); | |
} | |
Fragment fragment = getItem(position); | |
if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment); | |
if (mSavedState.size() > position) { | |
Fragment.SavedState fss = mSavedState.get(position); | |
if (fss != null) { | |
fragment.setInitialSavedState(fss); | |
} | |
} | |
while (mFragments.size() <= position) { | |
mFragments.add(null); | |
} | |
fragment.setMenuVisibility(false); | |
fragment.setUserVisibleHint(false); | |
mFragments.set(position, fragment); | |
mCurTransaction.add(container.getId(), fragment); | |
return fragment; | |
} | |
@Override | |
public void destroyItem(ViewGroup container, int position, Object object) { | |
Fragment fragment = (Fragment) object; | |
if (mCurTransaction == null) { | |
mCurTransaction = mFragmentManager.beginTransaction(); | |
} | |
if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object | |
+ " v=" + ((Fragment)object).getView()); | |
while (mSavedState.size() <= position) { | |
mSavedState.add(null); | |
} | |
mSavedState.set(position, fragment.isAdded() | |
? mFragmentManager.saveFragmentInstanceState(fragment) : null); | |
mFragments.set(position, null); | |
mCurTransaction.remove(fragment); | |
} | |
@Override | |
public void setPrimaryItem(ViewGroup container, int position, Object object) { | |
Fragment fragment = (Fragment)object; | |
if (fragment != mCurrentPrimaryItem) { | |
if (mCurrentPrimaryItem != null) { | |
mCurrentPrimaryItem.setMenuVisibility(false); | |
mCurrentPrimaryItem.setUserVisibleHint(false); | |
} | |
if (fragment != null) { | |
fragment.setMenuVisibility(true); | |
fragment.setUserVisibleHint(true); | |
} | |
mCurrentPrimaryItem = fragment; | |
} | |
} | |
@Override | |
public void finishUpdate(ViewGroup container) { | |
if (mCurTransaction != null) { | |
mCurTransaction.commitNowAllowingStateLoss(); | |
mCurTransaction = null; | |
} | |
} | |
@Override | |
public boolean isViewFromObject(View view, Object object) { | |
return ((Fragment)object).getView() == view; | |
} | |
@Override | |
public Parcelable saveState() { | |
Bundle state = null; | |
if (mSavedState.size() > 0) { | |
state = new Bundle(); | |
Fragment.SavedState[] fss = new Fragment.SavedState[mSavedState.size()]; | |
mSavedState.toArray(fss); | |
state.putParcelableArray("states", fss); | |
} | |
for (int i=0; i<mFragments.size(); i++) { | |
Fragment f = mFragments.get(i); | |
if (f != null && f.isAdded()) { | |
if (state == null) { | |
state = new Bundle(); | |
} | |
String key = "f" + i; | |
mFragmentManager.putFragment(state, key, f); | |
} | |
} | |
return state; | |
} | |
@Override | |
public void restoreState(Parcelable state, ClassLoader loader) { | |
if (state != null) { | |
Bundle bundle = (Bundle)state; | |
bundle.setClassLoader(loader); | |
Parcelable[] fss = bundle.getParcelableArray("states"); | |
mSavedState.clear(); | |
mFragments.clear(); | |
if (fss != null) { | |
for (int i=0; i<fss.length; i++) { | |
mSavedState.add((Fragment.SavedState)fss[i]); | |
} | |
} | |
Iterable<String> keys = bundle.keySet(); | |
for (String key: keys) { | |
if (key.startsWith("f")) { | |
int index = Integer.parseInt(key.substring(1)); | |
Fragment f = mFragmentManager.getFragment(bundle, key); | |
if (f != null) { | |
while (mFragments.size() <= index) { | |
mFragments.add(null); | |
} | |
f.setMenuVisibility(false); | |
mFragments.set(index, f); | |
} else { | |
Log.w(TAG, "Bad fragment at key " + key); | |
} | |
} | |
} | |
} | |
} | |
} |
public abstract class FragmentPagerAdapter extends PagerAdapter { | |
private static final String TAG = "FragmentPagerAdapter"; | |
private static final boolean DEBUG = false; | |
private final FragmentManager mFragmentManager; | |
private FragmentTransaction mCurTransaction = null; | |
private Fragment mCurrentPrimaryItem = null; | |
public FragmentPagerAdapter(FragmentManager fm) { | |
mFragmentManager = fm; | |
} | |
/** | |
* Return the Fragment associated with a specified position. | |
*/ | |
public abstract Fragment getItem(int position); | |
@Override | |
public void startUpdate(ViewGroup container) { | |
if (container.getId() == View.NO_ID) { | |
throw new IllegalStateException("ViewPager with adapter " + this | |
+ " requires a view id"); | |
} | |
} | |
@Override | |
public Object instantiateItem(ViewGroup container, int position) { | |
if (mCurTransaction == null) { | |
mCurTransaction = mFragmentManager.beginTransaction(); | |
} | |
final long itemId = getItemId(position); | |
// Do we already have this fragment? | |
String name = makeFragmentName(container.getId(), itemId); | |
Fragment fragment = mFragmentManager.findFragmentByTag(name); | |
if (fragment != null) { | |
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment); | |
mCurTransaction.attach(fragment); | |
} else { | |
fragment = getItem(position); | |
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment); | |
mCurTransaction.add(container.getId(), fragment, | |
makeFragmentName(container.getId(), itemId)); | |
} | |
if (fragment != mCurrentPrimaryItem) { | |
fragment.setMenuVisibility(false); | |
fragment.setUserVisibleHint(false); | |
} | |
return fragment; | |
} | |
@Override | |
public void destroyItem(ViewGroup container, int position, Object object) { | |
if (mCurTransaction == null) { | |
mCurTransaction = mFragmentManager.beginTransaction(); | |
} | |
if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object | |
+ " v=" + ((Fragment)object).getView()); | |
mCurTransaction.detach((Fragment)object); | |
} | |
@Override | |
public void setPrimaryItem(ViewGroup container, int position, Object object) { | |
Fragment fragment = (Fragment)object; | |
if (fragment != mCurrentPrimaryItem) { | |
if (mCurrentPrimaryItem != null) { | |
mCurrentPrimaryItem.setMenuVisibility(false); | |
mCurrentPrimaryItem.setUserVisibleHint(false); | |
} | |
if (fragment != null) { | |
fragment.setMenuVisibility(true); | |
fragment.setUserVisibleHint(true); | |
} | |
mCurrentPrimaryItem = fragment; | |
} | |
} | |
@Override | |
public void finishUpdate(ViewGroup container) { | |
if (mCurTransaction != null) { | |
mCurTransaction.commitNowAllowingStateLoss(); | |
mCurTransaction = null; | |
} | |
} | |
@Override | |
public boolean isViewFromObject(View view, Object object) { | |
return ((Fragment)object).getView() == view; | |
} | |
@Override | |
public Parcelable saveState() { | |
return null; | |
} | |
@Override | |
public void restoreState(Parcelable state, ClassLoader loader) { | |
} | |
/** | |
* Return a unique identifier for the item at the given position. | |
* | |
* <p>The default implementation returns the given position. | |
* Subclasses should override this method if the positions of items can change.</p> | |
* | |
* @param position Position within this adapter | |
* @return Unique identifier for the item at position | |
*/ | |
public long getItemId(int position) { | |
return position; | |
} | |
private static String makeFragmentName(int viewId, long id) { | |
return "android:switcher:" + viewId + ":" + id; | |
} | |
} |