1. 程式人生 > >Android recycleView 的一些優化與相關問題

Android recycleView 的一些優化與相關問題

這裡寫圖片描述

recycleView 也出來很長時間了,記錄一些自己見到的recycleView優化吧。

1.recyclerView.setHasFixedSize(true);

Item的高度是固定的,設定這個選項可以提高效能.總得來說就是就是避免整個佈局繪製。就是避免requestLayout.

具體的可以看看stackoverflow的這個幾個問題

設定這個可以避免重複的增刪造成而外的浪費資源

看完就差不多了

2.複用RecycledViewPool

總而言之
如果RecycledView的adapter是一樣的話可以考慮共享一個物件池。
比如說:
RecycledView巢狀RecycledView,裡面的RecycledView大部分都adapter都一樣。
這裡寫圖片描述

注意
如果 LayoutManager是LinearLayoutManager或其子類(如GridLayoutManager)
需要手動開啟這個特性:layout.setRecycleChildrenOnDetach(true)

例如:

class OuterAdapter extends RecyclerView.Adapter<OuterAdapter.ViewHolder> {
    RecyclerView.RecycledViewPool mSharedPool = new RecyclerView.RecycledViewPool();

    ...

    @Override
public
void onCreateViewHolder(ViewGroup parent, int viewType) { RecyclerView view = new RecyclerView(inflater.getContext()); LinearLayoutManager innerLLM = new LinearLayoutManager(parent.getContext(), LinearLayoutManager.HORIZONTAL); innerLLM.setRecycleChildrenOnDetach(true); innerRv.setLayoutManager(innerLLM); innerRv.setRecycledViewPool(mSharedPool); return
new OuterAdapter.ViewHolder(innerRv); } ...

3.橫向巢狀RecyclerView滑動資料預載入,setInitialItemPrefetchCount

注意只適合橫向巢狀
這裡寫圖片描述
在內部的 LayoutManager 中呼叫 LinearLayoutManager 的setInitialItemPrefetchCount()方法(25.1版本起可用)

innerLLM.setInitialItemsPrefetchCount(num);

num值看自己列表定把。不是越大越好。比如列表展示剛剛展示四個半item。就設定5.以此類推吧

想了解具體的可以看看這篇文章

4.RecyclerView 預載入,getExtraLayoutSpace

一開始我做這個漫畫預覽介面的時候就要用到提前載入圖片。上面那個巢狀的不管用,這裡要吐槽一下百度,-v-!mmp這搜尋都是一樣的答案!!!!!!.最後還是在stack overflow上才找到方案。

只要增加預留的額外空間,就是改變滑動時預判的範圍就可以了。

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this) {
    @Override
    protected int getExtraLayoutSpace(RecyclerView.State state) {
        return 300;
    }
};

具體的可以看看這兩個

5.特殊點的優化

如果你覺得你的記憶體還ok,也就是要RecyclerViews有個流暢的體驗。可以考慮設定下面的幾點

binding.fragmentCandidateBrowseList.setItemViewCacheSize(30);
binding.fragmentCandidateBrowseList.setDrawingCacheEnabled(true);
binding.fragmentCandidateBrowseList.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);

這裡寫圖片描述

來自於下面這篇文章,就是如何達到60fps。裡面一些優化也可以看看

6.RecycleView與NestedScrollView的巢狀

這是一個大坑,巢狀之後會發生一些奇奇怪怪的問題。

  1. 比如莫名的在中間顯示(焦點被搶)
  2. RecycleView滑動會感覺到卡頓,可以通過mRecyclerView.setNestedScrollingEnabled(false);解決這個問題
  3. 一次性載入所有item,而不是載入當前可見的Item,如果你的item佈局夠複雜或者條目很多,卡頓會很嚴重
  4. 相關屬性會失效,例如 linearManager.findLastVisibleItemPosition();獲取當前第一個可見的position等…

相關問題連結與對應的解決方案:

3,和4.的話我是就沒辦法解決了,看了stackoverflow上的回答,就是最好別用巢狀。
這裡寫圖片描述
 

7.RecycleView複雜佈局相關建議

剛剛上面有說道,儘量少用巢狀,可以避免很多不必要的坑。如果佈局複雜呢?一定要用到巢狀呢?

比如這個b站的這個直播佈局
這裡寫圖片描述

比較常見的佈局上優化
  1. 減少佈局的巢狀,減少佈局層次關係
  2. <include>,<merge>,<ViewStub>等標籤
多型別,多佈局

按照平常的思維,編寫上面的佈局,一般情況是這樣子的。
這裡寫圖片描述
這樣做是Ok的,但是隨著業務的增長,東西都堆積在一個 Adapter,所以會變得繁瑣,不好維護。

我一般是通過這種多佈局的方式去處理,把不用的業務分發到不同的viewHolder.

所以我這邊推薦我自認為還是ok的框架,小,且強大。

對你有幫助的話,不妨可以給我個開源專案start!感謝

暫時先到這裡,不定期更新!!!!!!!