FragmentStatePagerAdapter.notifyDataSetChanged不刷新頁面的解決的方法


公司做醫療產品的,顯示操作用的是android。所以我就用上下兩個部分大致是固定的,僅僅有中間會有6個頁面的切換,當中會有兩個用戶的切換。即普通用戶和管理員用戶,圖片能夠大致展示一下

其他頁面是同樣的,就這兩個頁面不一樣,以下的是管理員用戶,一想到其他頁面一樣的,中間就用了一個ViewPager,然后為了緩存多個頁面。用到了FragmentStatePagerAdapter,然后通過setOffscreenPageLimit(6)最多緩存了6個頁面,這樣一下,就不用操心每一個頁面的fragment的聲明周期對我項目的影響了。這個界面可能沒有。可是其他界面的檢測什么的,線程和Ui比較復雜。easy受fragment聲明周期影響而crash。

可是這個里有個奇怪的要求,管理員用戶的項目設置界面的功能居然不是全的,有兩個在普通用戶那邊。這個設計我也非常納悶,只是,還是得做啊,之后。就遇到了題目所說的問題,notifyDataSetChanged盡管會有頁面的增多和降低,可是。項目界面就是不刷新。

然后找了度娘和谷哥,出來的答案大多指向同一篇文章http://www.cnblogs.com/dancefire/archive/2013/01/02/why-notifyDataSetChanged-does-not-work.html,稍微看了一遍,照着上面方法試了。報錯。依然不得其要領,然后自己去看了下源代碼,攻克了。分享並記住這個問題,免得以后再犯錯

先進入notifyDataSetChanged

發現這句,mObservable,看名字,觀察者,應該就是用來實時監測viewPager綁定數據源的變化的。再進入notifychanged方法

發現一個遍歷。這個遍歷會去調用mObservers中的每個元素的變化。我們再進入onChanged,

到了,這里,發現onChanged僅僅是一個抽象類中的方法。,既然會調用,肯定會被重寫咯,找了一圈。在viewPager中的內部內繼承了。


躲的還是蠻深的,只是這還沒有找到我們須要關注的地方,那就繼續找,dataSetChanged

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 (ii.position != newPos) {
                if (ii.position == mCurItem) {
                    // Our current item changed position. Follow it.
                    newCurrItem = newPos;
                }

                ii.position = newPos;
                needPopulate = true;
            }
        }

        if (isUpdating) {
            mAdapter.finishUpdate(this);
        }

        Collections.sort(mItems, COMPARATOR);

        if (needPopulate) {
            // Reset our known page widths; populate will recompute them.
            final int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = getChildAt(i);
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                if (!lp.isDecor) {
                    lp.widthFactor = 0.f;
                }
            }

            setCurrentItemInternal(newCurrItem, false, true);
            requestLayout();
        }
    }
這里就是我們須要關注的地方了,一看這么多。確實有點頭疼。只是,我們僅僅關注重點,看第13行,有句
final int newPos = mAdapter.getItemPosition(ii.object);

這里就調用的了我們的adapter中的getItemPosition,我們再看看getItemPosition會返回什么,會接收什么,復寫fragmentStatePagerAdapter中的getItemPosition方法,發現僅僅會返回父類中的方法

接着看父類中的方法

再看看POSITION_UNCHANGED是干嘛用的。


馬丹,這下總算是明確了,這里一直return POSITION_UNCHANGED;

return一個“未改變”的標志給dataSetChanged()中,它當然打死都不更新咯。請看dataSetChanged()中的第15-17行


魂淡,居然知道原因了。那就好做了。直接將要刷新的頁面 return POSITION_NONE

@Override
    public int getItemPosition(Object object) {
        if (object.getClass().getName().equals(ProjectFragment.class.getName())
                || object.getClass().getName().equals(ProjectFragment2.class.getName())) {
            return POSITION_NONE;
        }
        return super.getItemPosition(object);
    }



免責聲明!

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



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