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消失.

解決辦法:

依然在這個適配器里重寫public int getItemPosition(@NonNull Object object)方法

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_NONE

為什么呢?

  為什么我改了這個之后就可以在刪除item后更新view了呢?好奇心害死貓,我們進一步探究一下.

  首先我們看看 return super.getItemPosition(object); 父類里寫的返回值到底里面有啥

  

    /**
     * 在主視圖嘗試確定項目的位置時調用
     * 已經改變。 如果給定的位置,則返回{@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;
    }

 

很好上面的意思是

如果視圖item已經是加載過的,就使用 POSITION_UNCHANGED 來標識,表示這個item不需要重復更新

如果item在適配器里不存在,就說item未加載過,就使用 POSITION_NONE 來標識,標識這個item需要更新一次

接着繼續探究下ViewPager是怎么調用getItemPosition()的

 

 

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真會寫方法名稱...

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM