ViewPager+Fragment LazyLoad 最優解

發表於2016-07-05

ViewPager+Fragment的模式再常見不過了,以國民應用微信為例,假設微信也是ViewPager+Fragment的實現方式,那表現形式上就是一個ViewPager管理了四個Fragment,左右滑動來回切換。但是ViewPager有一個奇葩的特性叫:預載入,比如開啟微信,首先看到的是第一個Tab(微信),但事實上第二個Tab(通訊錄)已經載入好了。當選擇第二個Tab(通訊錄),第三個Tab(發現)已經載入好了,以此類推。

但上述ViewPager+Fragment的這種組合並不完美,因為我希望使用者選擇了哪個Tab再去載入哪個Tab的資料,而不要去做預載入,假如當前頁面和預載入頁面都有大量的網路請求,可能就會比較慢,有很多請求在排隊。關於這個問題,也有很偏激的做法,比如棄用ViewPager,自己手動管理Fragment,或者直接禁掉ViewPager預載入。有一種比較合適的方案是保持ViewPager預載入的特性,但是隻初始化View,選擇當前Tab的時候再進行網路請求。關於這一方案的實現,也是眾說紛紜,千奇百怪。最後,還是選擇男神Stay的方案。

直接上程式碼。

這是一個父類,看程式碼這裡只有一個setUserVisibleHint需要說下,這是一個相當生僻的方法,我們可以用這個方法來判斷當前UI是否可見,所以在prepareFetchData方法裡我們做如下判斷:就是當前UI可見,並且fragment已經初始化完畢,如果網路資料未載入,那麼請求資料,或者需要強制重新整理頁面,那麼也去請求資料,So easy。子Fragment只需要繼承父類,實現抽象方法,在fetchData()裡做網路請求或者其他耗時操作即可。再在寫個子類吧。

如果你也有這樣的需求或者煩惱,保證藥到病除。

有同學說實踐過程中遇到了些問題,比如Fragment只重新整理一次,這個問題只要手動呼叫prepareFetchData(),傳true即可強制重新整理了。還有同學質疑setUserVisibleHint()和onActivityCreated()的執行先後的問題。關於這個請看下圖。

 

1187237-d0ef5e00b8806c6c

相關文章