问题
在进行Fragment的添加和删除时,适配器刷新之后发现并没有什么变化,这是为什么呢?
理解
1. FragmentPagerAdapter
适合少量的页面显示。该类每一个生成的Fragment对象都会储存在内存中,所以适合相对静态、页面少的情况,如果是页面多,且Fragment的处理相对动态(添加、删除等)时,使用FragmentStatePagerAdapter较为适合。
2. FragmentStatePagerAdapter
适合大量的页面显示,当页面处于不可见时,可能会被销毁,只保留该片段的保存状态。与FragmentPagerAdapter切换页面产生的大量开销对比,这允许了适配器保持与每个被访问页面相关联的更少的存储器。
分析
在切换页面时,FragmentPagerAdapter与FragmentStatePagerAdapter对于上上页(预加载默认1,所以取上上页)的处理是不相同的,FragmentPagerAdapter只是销毁对应Fragment的视图,而FragmentStatePagerAdapter则是把Fragment的实例和视图都销毁了。
当我们对页面进行动态处理时,添加(或删除)是对适配器所持有的list对象进行长度的变化,操作完之后就进行适配器的刷新,也就是notifyDataSetChanged方法,先看看该方法:
//PagerAdapter.class
public void notifyDataSetChanged() {
synchronized (this) {
if (mViewPagerObserver != null) {
//根据源码可知mViewPagerObserver的对象是ViewPager里面PagerObserver类的实例
mViewPagerObserver.onChanged();
}
}
mObservable.notifyChanged();
}
//ViewPager.class
private class PagerObserver extends DataSetObserver {
PagerObserver() {
}
@Override
public void onChanged() {
//调用的是该方法
dataSetChanged();
}
@Override
public void onInvalidated() {
dataSetChanged();
}
}
对FragmentPagerAdapter(或FragmentStatePagerAdapter)执行的方法大概进行注释一下,方便理解,
//ViewPager.class
void dataSetChanged() {
// This method only gets called if our observer is attached, so mAdapter is non-null.
final int adapterCount = mAdapter.getCount();
mExpectedAdapterCount = adapterCount;
boolean needPopulate = mItems.size() < mOffscreenPageLimit * 2 + 1
&& mItems.size() < adapterCount;
int newCurrItem = mCurItem;
boolean isUpdating = false;
//遍历所有item
for (int i = 0; i < mItems.size(); i++) {
final ItemInfo ii = mItems.get(i);
//先调用adapter的getItemPosition方法,获得newPos值
final int newPos = mAdapter.getItemPosition(ii.object);
if (newPos == PagerAdapter.POSITION_UNCHANGED) {
continue;
}
if (newPos ==