RecyclerView使用封裝與優化

   最近優化了項目裏的列表展現,順便對RecyclerView的使用作了從新的封裝,目的是當列表的需求比較複雜的時候,依然可以保持邏輯的清晰和解耦,同時經過封裝來使複雜列表的性能獲得必定的保證。git

固然若是是很是簡單的列表的話,其實Android原生的RecyclerView加上Adapter就已經比較便捷了,沒有必要去作過分的封裝了。github

項目GitHub地址: github.com/zhengcx/Ins…markdown

   每個對項目的重構或者從新封裝都是出於對現狀的不滿,那麼咱們就從這個封裝項目解決了哪些問題來展開這篇博文吧。oop

1.解決重複的全局刷新

   須要注意一下你的項目裏對列表的使用,特別是加載更多時是否都是重複的全局刷新,這對複雜列表的性能影響較大,你須要考慮每次刷新不去刷新那些不須要刷新的item,一個是對性能會有提升,另外一個頁面上用戶的體驗也會好不少,本項目提供了全局刷新和增量刷新的相關方法,保證加載更多或者操做單個item時只局部刷新。佈局

2.解決header/Footer的增刪效率

   RecyclerView自己並無提供像ListView那樣便捷的添加header/footer的方法,因此須要咱們本身去實現。性能

網上主要有兩種:一種是採用wrap的方式使header、footer和普通item區別開,而另外一種方式使把header、footer也當作是一種itemType來作。優化

   這裏咱們採用了第二種方式,提供了便捷添加header/footer的方法,固然把header\footer當作一種itemType來看待,則當header/footer發生增刪(特別是header)時,則會使列表發生全局的刷新,這裏優化的點是對RecyclerView來講他的header永遠只有一個,是一個ViewGroup,以後要添加或者刪除一個或多個header,都只是往這個ViewGroup裏增刪View,將不會對整個列表產生刷新,提供性能和體驗。spa

3. 解決列表多itemType時代碼不夠清晰的問題

   當你的列表會存在多種複雜的itemType時,很容易時Adapter裏的代碼產生混亂,且不夠清晰,很難拓展。咱們封裝的目的是:code

1.讓每種itemType的處理邏輯交給各自的itemDelegate去處理,實現不一樣itemType處理邏輯的解耦orm

2.讓代碼易於拓展,也就是說無論從此要再添加多少種itemType,都能作到很是清晰,很是便捷。

項目裏經過DelegateScheduler來管理調度不一樣itemType的處理邏輯,使多itemType變得清晰易拓展。

4.解決狀態View致使過分繪製的問題

   咱們的列表一般都須要好幾種顯示加載狀態的View,好比loadingView、加載失敗View、加載數據爲空View。若是你的作法是在佈局文件裏先寫好這幾種View而後經過設置是否可見來控制,顯然這會引發佈局嵌套過渡繪製的問題,固然你能夠利用ViewStub來作一些優化,可是治標不治本,當這些狀態View被inflate一次後,依然會存在這種問題。

   若是你把這些狀態View也當作是一種itemType呢,讓它與普通item同樣參與回收,參與cache,是否是就能夠解決這個問題,這是我目前看到想到的比較理想的方式,固然可能有更好的方式。

5.解決上拉加載更多問題

   顯然若是你把上拉加載更多這個功能放在你的業務代碼裏去監聽是不合適的,咱們須要封裝一下,讓recyclerView自動就帶有這個功能,直接使用就能夠了。

   本項目給上拉加載更多提供了兩種不一樣的監聽方式,看我的喜愛本身選擇。

1.實時監聽,也就是說只要用戶滑動,那麼就會實時監聽判斷要不要開始加載下一頁數據,這一種的好處是讓列表預加載更加實時,基本能夠實時用戶能夠不斷的下拉,使用戶感知不到咱們的加載過程。

2.另外一種是隻有當列表滾動狀態發生改變時纔會發起是否加載下一頁數據的判斷,這一種基本是用戶從滑動到中止時纔會發起下一頁的加載。

固然兩種方式提早多少個item發起預加載下一頁都是能夠由你本身來設置這個參數,目前默認是採用第二種方式,能夠經過設置來使用第一種方式。

6. 解決item的點擊事件重複綁定的問題

   RecyclerView沒有像ListView那樣提供setOnItemCLickListener()方法來綁定item的點擊事件,因此咱們通常都會本身去設置這個item的點擊事件,這樣子很容易就把點擊事件屢次重複設置了。

   這裏封裝提供了setOnItemClickListener()方法,讓你能夠放心的設置item點擊事件,而且在回調裏提供該item所綁定的數據,以及item的position,該item的類型等重要信息,可使你在多種itemType的列表裏的點擊事件里正確的作各類你想作的事情。

對列表性能問題的建議

   其實對於一些複雜的列表,性能問題顯得尤其重要,上面說了一個是儘可能去作局部刷新而不是全量刷新,一個是儘可能減小過分繪製。還有一個很是重要的是每一個版本都要去關注你的bindViewHolder()裏的邏輯是否有耗時嚴重的方法或操做,列表性能出現問題,很大機率就是你的bindViewHolder()中有叫耗時操做,排查也很好排查,經過SysTrace+TraceView能夠很快找到耗時的方法和性能的瓶頸,而後作針對性的優化就能夠了。

項目GitHub地址: github.com/zhengcx/Ins…

最後,但願世界上的每個列表都絲絲如滑~~~

相關文章
相關標籤/搜索