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的巢狀
這是一個大坑,巢狀之後會發生一些奇奇怪怪的問題。
- 比如莫名的在中間顯示(焦點被搶)
- RecycleView滑動會感覺到卡頓,可以通過mRecyclerView.setNestedScrollingEnabled(false);解決這個問題
- 一次性載入所有item,而不是載入當前可見的Item,如果你的item佈局夠複雜或者條目很多,卡頓會很嚴重
- 相關屬性會失效,例如 linearManager.findLastVisibleItemPosition();獲取當前第一個可見的position等…
相關問題連結與對應的解決方案:
3,和4.的話我是就沒辦法解決了,看了stackoverflow上的回答,就是最好別用巢狀。
7.RecycleView複雜佈局相關建議
剛剛上面有說道,儘量少用巢狀,可以避免很多不必要的坑。如果佈局複雜呢?一定要用到巢狀呢?
比如這個b站的這個直播佈局
比較常見的佈局上優化
- 減少佈局的巢狀,減少佈局層次關係
- <include>,<merge>,<ViewStub>等標籤
多型別,多佈局
按照平常的思維,編寫上面的佈局,一般情況是這樣子的。
這樣做是Ok的,但是隨著業務的增長,東西都堆積在一個 Adapter,所以會變得繁瑣,不好維護。
我一般是通過這種多佈局的方式去處理,把不用的業務分發到不同的viewHolder.
所以我這邊推薦我自認為還是ok的框架,小,且強大。
對你有幫助的話,不妨可以給我個開源專案start!感謝
暫時先到這裡,不定期更新!!!!!!!