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; for (int i = 0; i < mItems.size(); i++) { final ItemInfo ii = mItems.get(i); //========核心方法========================= final int newPos = mAdapter.getItemPosition(ii.object);
if (newPos == PagerAdapter.POSITION_UNCHANGED) { continue; }
if (newPos == PagerAdapter.POSITION_NONE) { mItems.remove(i); i--;
if (!isUpdating) { mAdapter.startUpdate(this); isUpdating = true; }
@Override public Object instantiateItem(ViewGroup container, int position){ if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction(); }
finallong 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; }
如果没有重写该方法,那么,在增减数据后,即使 getItemPosition 判定数据变化,再通过 makeFragmentName(container.getId(), itemId) (itemId 默认是position)获取的 tag 还是不变,那么重新拿到的 fragment 和原来位置的 fragment 一样,,所以必须通过重写 getItemId 来修改 tag,使这数据源中的 fragment 和这个 tag 形成唯一个关联关系,一般唯一性用hashCode就足够了。示例代码如下:
@Override public Fragment getItem(int position){ SimpleFragment fragment = (SimpleFragment) data.get(position); fragment.setPosition(position); return fragment; }