一、背景
RecyclerView的優化有很多機制,一般來說主要分爲:
(1)ViewHolder 緩存預加載
這類主要提前填充ViewHolder緩存或者共享ViewHolder來實現
(2)圖片預加載
利用ScrollListener機制,預測滑動方向,但是存在明顯的雞肋就是ImageView或者ImageView所在的Item儘可能的相似,如果RecylerView的複用時算法複雜度越高,性能增益也會越低,主要取決於viewType數量和各種View的交替複雜度。
(3)局部更新
一般很難去使用單個的notifyItemXXX方法,但是Android提供了一個比較好的工具,DiffUtil來優化,但是缺點是大部分場景必須複寫equals和hashcode,不過收益也不錯。
(4)動畫
動畫在低配設備上差異很明顯,特別是幀動畫,alpha動畫 (alpha動畫是離屏渲染2次,且緩存會被回收),如果能避免動畫儘可能避免,特別是低端機型。
(5) 對象、資源共享
不需要爲每個ItemView去new 一個監聽器
Drawable可以ConstantState.newDrawable或者mutate複用
(6)減少RequestLayout
這裏特別說一下TextView,看似簡單,實際上性能損耗不少
(9)不使用inflater
inflater確實又些性能損耗
(10)
不給ImageView設置圖片或者背景
二、可是區域優化-預佈局
getExtraLayoutSpace
返回 LayoutManager 應佈置的額外空間量。
默認情況下,LinearLayoutManager 在平滑滾動時額外放置 1 頁項目,否則爲 0。您可以覆蓋此方法以實現您的自定義佈局預緩存邏輯。
注意:佈置不可見元素通常會帶來顯着的性能成本。它通常只適用於平滑滾動到未知位置等地方,其中 1) 額外的內容有助於 LinearLayoutManager 提前知道其目標何時接近,因此它可以儘早平滑地減速,以及 2) 當運動是連續的。
如果在用戶可能改變滾動方向的情況下擴展額外的佈局空間,代價尤其昂貴。改變方向將導致額外的佈局空間交換到視口的另一側,導致許多重新綁定/回收,除非緩存足夠大以處理它。
返回值:應佈置的額外空間(以像素爲單位)。
此方法是一把雙刃劍,對於ViewType較少的情況,實際上增益並不大,反而有損內存空間,但是對於ViewType交錯排列的情況,反而是一種改善方式,但是最好不要超過1屏的高度。另外也可以很好的結局TV上焦點移動時,新View未加載,focus Down 時焦點亂飛的問題。