Android開發 ViewPager刪除Item後,不會更新數據和View

問題描述: 

  在使用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真會寫方法名稱...
相關文章
相關標籤/搜索