1. 程式人生 > >ScrollView巢狀ViewPager自適應高度

ScrollView巢狀ViewPager自適應高度

由於專案需要,ScrollView 巢狀ViewPager載入Fragment再包裹RecyclerView等控制元件來實現一系列功能。在此主要是關於載入資料,ViewPager動態設定高度的問題以及載入資料,滑動不卡頓。做總結。

問題:ViewPager在ScrollView的包裹下,無論高度是設定match_parent,或是wrap_content,都無法加載出fragment中的資料,必須設定確定直才能顯示,(500dp),給定確定值以後,資料上拉載入無法實現。因此我們必須要動態計算fragment中RecyclerView的高度,動態的賦高度給ViewPager.

先上圖,由於上傳不了短視訊,沒有製作gif,就看圖片吧,文章下面,有下載的連結

挖坑:動態設定ViewPager高度,最初的實現思路,計算ViewPager當前選中的View(Fragment)的高度。

ViewPager滑動監聽的方法中,onPageSelected(intposition),可以獲得當前的選中的View的下標位置。

我在重寫ViewPager的類中,使用滑動監聽傳入的下標位置來取得當前的View,的高度。

@Override
public void onPageSelected(int position) {
    viewPager.resetHeight(position);
}
實踐證明,現實和想法還是有差距的,執行切換,指向view為null,列印多遍log,以及查閱資料,才知道
viewPager只會維持2-3個view,滑動時載入和刪除view,然而傳入的current,可以是無限的,,,
解決方法:
遍歷ViewPager所有的子View,得到高度,賦值給ViewPager。這樣寫,是解決了view為null的問題,並且也給ViewPager設定了高度,
但是,切換頁面時,子View的高度與最大的子View的高度不匹配,就會導致,頁面下一大片空白部分。
解決方法:計算當前view的高度,並賦值給viewPager。ViewPager下的Fragment中,包含RecyclerView,的高度,
於是,我在RecyclerView的介面卡中,累加計算item的高度,得到總和後,賦值給ViewPager,解決了頁面空白的部分,
但是,滑動載入到很多頁以後,明顯感覺螢幕卡頓嚴重的問題。所以,還是需要思考優化。。。。。
參考了鴻洋的部落格,使用HashMap,根據下標位置,來儲存每一個View。具體如下:
ok,到這裡為止,核心的程式碼基本是可以解決了,可以正常取到當前的View,並且獲得高度。
但是還是有一些,微微的卡頓的問題,思考完善之後,在程式碼中模擬了網路載入資料的情況,進行分析,
以下幾點比較容易遺忘和需要優化的地方。
上面程式碼有沒毛病?正常來講,這樣寫,還是會實現資料載入,高度計算等。但是你會發現越來越卡,卡到你懷疑人生。
於是,,,我思考了這幾行程式碼的順序,,,當前的Fragment的顯示的時候,setUserVisibleHint() 方法呼叫,訪問網路資料,
viewPager監聽到onPageSelected(),方法,計算當前頁面的高度,此時可能出現網路卡頓,又或者,你得到了返回的網路資料,
並且關閉了,refresh的重新整理方法,但是adapter可能還沒載入完資料,所以導致載入卡頓,滑動不流暢等問題。解決如下:
在Fragment中,沒有使用,setUserVisibleHint()方法,來執行getData(),在監聽的onPageSelected()方法中,執行getData(),
保證獲取資料,在前,計算高度在後,回到Fragment中,在Handler中,資料載入,填充,重新整理,在前,關閉progressDialog,refresh
在後,確保重新整理完資料(與計算高度相關),再關閉。能夠很好的提升頁面的流程度。
原始碼下載