1. ViewPager的简单适配器PageAdapter
参看文章第一二小节
实现PageAdaper必须实现它的4个方法
getCount()
返回页面页面数量
Object instantiateItem(ViewGroup container, int position)
将页面的view加入container中, 并返回对应的的key
boolean isViewFromObject(View view, Object object)
判断页面的view和key是否匹配
void destroyItem(ViewGroup container, int position, Object object)
将第position页的view从container中移除
2.使用FragmentPageAdapter
实现两个方法 (FragmentPageAdapter实现了instantiateItem,isViewFromObject,destroyItem)
public int getCount()
返回页面页面数量
Fragment getItem(int position)
返回第position页的Fragment
注意 如下FragmentPagerAdapter的源码
- instantitatItem首先从FragmentManager中获取Fragment
如果没有,则再从getItem中获取
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;
}
2 . destroyItem
从FragmentMananger detach掉Fragment,此时Fragment仍然在FragmentManager中
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);
}
3. FragmentPagerStateAdapter
仍然只需要实现 getCount() 和instantiateItem()方法
FragmentPagerStateAdapter相关源码
- instantitatItem 逻辑和FramentPagerAapter类似
首先从FragmentManager中获取Fragment
如果没有,则再从getItem中获取
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;
}
2 . destroyItem
从FragmentMananger remove掉Fragment,此时Fragment不在FragmentManager中
@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与FragmentPagerStateAdapter的区别
实例
- viewpager.setOffscrennPageLimit(1);
- 从第一页滑动第二页,会创建第三页
- 从第二页滑到第一页,会调用destroyItem摧毁第三页
- 区别在于FragmentPagerAdapter与FragmentPagerStateAdapter的destoryItem方法实现不一样。FragmentPagerAdapter会将Fragment从FragmentManger总detach()
FragmentPagerStateAdapter会将Fragment从FragmentManger总remove()