參考:
http://cammykamal.blogspot.hk/2015/05/fragmentstatepageradapter-vs.html
看了一大段英文,勉強懂得一些,但還是看源碼來的快;
最大的區別就是:
- FragmentPagerAdapter:不會摧毀Fragment實例,只會摧毀Fragment 的View;
特別注意:實例與Fragment的View是有區別的;沒有真正摧毀,只是調用了detach
方法,此時Fragment的成員變量,如:List<Bitmap>,會一直存在并占用著內存,如果多個Fragment都含有占用內存的成員變量,最好不要使用FragmentPagerAdaper,則使用下面的StatePagerAdappter; - FragmentStatePagerAdapter:直接摧毀Fragment,即調用remove方法,但移除之前,會保存Fragment相關的狀態,我們可以在 onSaveInstance 等相關方法中來進行數據的保存;
具體代碼:
- 初始化方法(instantiateItem):
- FragmentPagerAdapter:
@Override public Object instantiateItem(ViewGroup container, int position) { // 省略部分代碼 final long itemId = getItemId(position); String name = makeFragmentName(container.getId(), itemId); // 這里先查找 Fragment fragment = mFragmentManager.findFragmentByTag(name); if (fragment != null) { // 找到了,直接 attach mCurTransaction.attach(fragment); } else { // 否則創建新的fragment,并添加 fragment = getItem(position); mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId)); } // 省略部分代碼 return fragment; }
- FragmentStatePagerAdapter:
@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;
}
}
// 省略部分代碼
// 獲取fragment,有狀態則還原
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);
}
}
// 省略代碼
mCurTransaction.add(container.getId(), fragment);
return fragment;
}
- 銷毀方法(destroyItem)
- FragmentPagerAdapter:
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); // detach 的,只是銷毀View }
- FragmentStatePagerAdapter:
@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); // 直接移除了 }
- FragmentPagerAdapter: