FragmentStatePagerAdapter.notifyDataSetChanged不重新整理頁面的解決辦法

來源:互聯網
上載者:User

標籤:android   fragmentstatepagerad   notifydatasetchanged   

公司做醫學產品的,顯示操作用的是android,所以我就用上下兩個部分大致是固定的,只有中間會有6個頁面的切換,其中會有兩個使用者的切換,即普通使用者和管理使用者,圖片可以大致展示一下

其它頁面是相同的,就這兩個頁面不一樣,下面的是管理使用者,一想到其它頁面一樣的,中間就用了一個ViewPager,然後為了緩衝多個頁面,用到了FragmentStatePagerAdapter,然後通過setOffscreenPageLimit(6)最多緩衝了6個頁面,這樣一下,就不用擔心每個頁面的fragment的聲明周期對我項目的影響了,這個介面可能沒有,但是其它介面的檢測什麼的,線程和Ui比較複雜,容易受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);    }


FragmentStatePagerAdapter.notifyDataSetChanged不重新整理頁面的解決辦法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.