viewPager+fragment如何重新整理緩衝fragment,viewpagerfragment

來源:互聯網
上載者:User

viewPager+fragment如何重新整理緩衝fragment,viewpagerfragment

 

最近在做一個項目,有一個功能是答題翻頁。於是需要實現在這一頁的時候就緩衝下一頁。

剛剛開始我是用

setOnPageChangeListener方法監聽,滑到這一頁的時候才重新整理這一頁:
 public void onPageSelected(int position){   ReadFragment fragment= (ReadFragment) fragmentArrayList.get(position);   fragment.refresh();}


不過這樣就只有滑動到這一頁的時候才能用fragmentArrayList.get(position)擷取當前頁,用這種方法擷取下一頁的fragment就會報null 指標。也就是說無法先緩衝重新整理下一頁的內容。

到底怎麼樣才能擷取得到下一頁的fragment呢?

百度了一下好像說要在

FragmentPagerAdapter裡面的instantiateItem()處理。於是我看了一下它的原始碼:
@Override    public Object instantiateItem(ViewGroup container, int position) {        if (mCurTransaction == null) {            mCurTransaction = mFragmentManager.beginTransaction();        }        final long itemId = getItemId(position);        // Do we already have this fragment?        String name = makeFragmentName(container.getId(), itemId);        Fragment fragment = mFragmentManager.findFragmentByTag(name);        if (fragment != null) {            if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);            mCurTransaction.attach(fragment);        } else {            fragment = getItem(position);            if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);            mCurTransaction.add(container.getId(), fragment,                    makeFragmentName(container.getId(), itemId));        }        if (fragment != mCurrentPrimaryItem) {            fragment.setMenuVisibility(false);            fragment.setUserVisibleHint(false);        }        return fragment;    }

可以看出:instantiateItem方法中並不是直接去List裡面拿到Fragment,而是先從FragmentManager中通過Tag找對應的Fragment,如果可以找到就不會去List裡面拿了,介於這種情況,我在adapter中加入了這個方法:

 

 public ReadFragment getFragment(int position)    {        String tag = getFragmentTag(mContainer.getId(),position);        ReadFragment fragment = (ReadFragment) fm.findFragmentByTag(tag);        return fragment;    }    /**     * 運用反射機制調用FragmentPagerAdapter的getFragmentTag的方法     * @param viewId     * @param index     * @return     */    private String getFragmentTag(int viewId, int index)    {        try {            Class<FragmentPagerAdapter> cls = FragmentPagerAdapter.class;            Class<?>[] parameterTypes = { int.class, long.class };            Method method = cls.getDeclaredMethod("makeFragmentName",                    parameterTypes);            method.setAccessible(true);            String tag = (String) method.invoke(this, viewId, index);            return tag;        } catch (Exception e) {            e.printStackTrace();            return "";        }    }

 

在onPageSelected裡面調用getFragment(int position)方法,達到當選中這一頁的時候就先緩衝重新整理下一頁。

getFragment(int position)方法其實就是拿到緩衝的fragment,不過就得先保證該fragment已經先在viewpager中緩衝了,雖然內容還沒有重新整理,這樣就不會報null 指標了。

出現了一個問題,onPageSelected在viewPager展示第一頁的時候是不會調用的,所以第一頁的內容還是得另外重新整理,無法在onPageSelected裡面重新整理。

建立一個方法initData(),在裡面重新整理。

由於viewPager展示第一頁的時候不會調用onPageSelected,那也就導致了第一頁和第二頁的內容都無法先得到緩衝,所以第一頁和第二頁的內容都得在initData裡面單獨重新整理,其它的通過onPageSelected裡面的方法來重新整理。

 

到了這裡總結一下思路:

剛剛進入介面的時候:重新整理第一頁,緩衝第二頁。

翻頁時候:從第一頁翻到第二頁,執行onPageSelected()

              onPagerSelected裡面調用方法getFragment(int position),擷取到下一頁即第三頁的fragment,然後重新整理緩衝內容。

              從第二頁翻到第三頁:執行onPageSelected()

              onPagerSelected裡面調用方法getFragment(int position),擷取到下一頁即第四頁的fragment,然後重新整理緩衝內容。

 

結果又出現了又一個問題:從第一頁翻到第二頁的時候,閃退了,報null 指標。

後來調試了一下發現getFragment方法得到的fragment為null,沒道理,為啥,想到最後才發現原來是因為第三頁的fragment在viewPager中沒有緩衝,而我們的getFragment是在緩衝中通過tag標記來拿的。

怎麼才能讓第三個fragment在viewPager中實現得到緩衝呢?

 

預設的,viewpager在第一頁的時候會緩衝第二頁,到了第二頁的時候會緩衝第一與第二頁(這裡的緩衝是指組件不是指內容都是一樣的),實踐證明,只有當第二頁完全顯示的時候,第三頁才會得到緩衝,而onPagerSelected在fragment滑到超過螢幕一半而且我們手指放開了才會調用,如果我們的手指沒有放開是不會被調用的,當我們的手指放開,onPagerSelected被調用的時候,第三頁還沒有得到緩衝。

 

怎麼辦,我又想到了

@Override public void onPageScrollStateChanged(int state) {}
本認為可以在裡面判斷state==2,即滑動停止的時候,才緩衝重新整理這一頁,最後才發現一樣問題

原來滑動停止指的是手指的滑動,即手指離開螢幕,而不是指改fragment的滑動。

怎麼辦,不用怕:還有一個方法:readViewPager.setOffscreenPageLimit(2);

該方法可以給你答案。

這個方法可以設定viewPager當前頁兩邊的緩衝數目,readViewPager.setOffscreenPageLimit(2);當前頁左右各緩衝2個。viewPager預設的是readViewPager.setOffscreenPageLimit(1);

這樣就OK了?,高興太早了。滑到第五頁的時候出問題了,是空白的。改為readViewPager.setOffscreenPageLimit(3);也一樣。

 

(此時我總共只有4個fragment,我採用的是無限迴圈模式,實際的fragment有4個)而實際緩衝的有5個fragment(當前頁加左右兩個),會不會是這裡出問題。

於是我把fragment改為5個,結果沒問題了。

但是往回翻頁的時候出問題了,翻幾頁後又出現了空白頁,於是我改為6個fragment,才完全沒問題。暈。

還有往回翻頁也需要重新整理緩衝內容。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.