在使用ViewPager的適配器刪除適配器裏一個Item後依然會,而刪除的這個item依然會保留緩存,適配器不會從新加載更新數據.以下代碼:緩存
public class TReleaseCircleZoomablePagerAdapter extends PagerAdapter { private List<TReleaseCircleBase.Pic> mImageUrlList = new ArrayList<>(); public void removeItem(int position){ mImageUrlList.remove(position); notifyDataSetChanged(); } //....略
在這個代碼裏removeItem(int position)是但願清理適配器List裏的一項item,而且從新刷新.可是其實真實狀況是並不會從新刷新...... 在滑動超過3個頁面後纔會讓你那個刪除item消失.ide
依然在這個適配器裏重寫public int getItemPosition(@NonNull Object object)方法this
public class TReleaseCircleZoomablePagerAdapter extends PagerAdapter { private List<TReleaseCircleBase.Pic> mImageUrlList = new ArrayList<>(); public void removeItem(int position){ mImageUrlList.remove(position); notifyDataSetChanged(); } @Override public int getItemPosition(@NonNull Object object) { // return super.getItemPosition(object); return POSITION_NONE; } //略......
注意關鍵點是返回 POSITION_NONEgoogle
爲何我改了這個以後就能夠在刪除item後更新view了呢?好奇心害死貓,咱們進一步探究一下.spa
首先咱們看看 return super.getItemPosition(object); 父類裏寫的返回值到底裏面有啥
code
/** * 在主視圖嘗試肯定項目的位置時調用 * 已經改變。 若是給定的位置,則返回{@link #POSITION_UNCHANGED} * 若是適配器中再也不存在該項,則item未更改或{@link #POSITION_NONE}。 * * <p>The default implementation assumes that items will never * change position and always returns {@link #POSITION_UNCHANGED}. * * @param object Object representing an item, previously returned by a call to * {@link #instantiateItem(View, int)}. * @return object's new position index from [0, {@link #getCount()}), * {@link #POSITION_UNCHANGED} if the object's position has not changed, * or {@link #POSITION_NONE} if the item is no longer present. */ public int getItemPosition(@NonNull Object object) { return POSITION_UNCHANGED; }
很好上面的意思是server
若是視圖item已是加載過的,就使用 POSITION_UNCHANGED 來標識,表示這個item不須要重複更新blog
若是item在適配器裏不存在,就說item未加載過,就使用 POSITION_NONE 來標識,標識這個item須要更新一次rem
接着繼續探究下ViewPager是怎麼調用getItemPosition()的get
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; } mAdapter.destroyItem(this, ii.position, ii.object); needPopulate = true; if (mCurItem == ii.position) { // Keep the current item in the valid range newCurrItem = Math.max(0, Math.min(mCurItem, adapterCount - 1)); needPopulate = true; } continue; }
上面的if (newPos == PagerAdapter.POSITION_UNCHANGED) 和 if (newPos == PagerAdapter.POSITION_NONE) 就已經破案了...,只能說google真會寫方法名稱...