性能優(yōu)化-使用RecyclerView的正確姿勢

前言

本文是在作者Blankj基礎(chǔ)上補(bǔ)充一些RecyclerView的正確姿勢Tips 持續(xù)更新~

數(shù)據(jù)處理和視圖加載分離

我們知道,從遠(yuǎn)端拉取數(shù)據(jù)肯定是要放在異步的混埠,在我們拉取下來數(shù)據(jù)之后可能就匆匆把數(shù)據(jù)丟給了 VH 處理誓酒,其實(shí),數(shù)據(jù)的處理邏輯我們也應(yīng)該放在異步處理貌亭,這樣 Adapter 在 notify change 后柬唯,ViewHolder 就可以簡單無壓力地做數(shù)據(jù)與視圖的綁定邏輯,比如:

mTextView.setText(Html.fromHtml(data).toString());

這里的 Html.fromHtml(data) 方法可能就是比較耗時(shí)的圃庭,存在多個(gè) TextView 的話耗時(shí)會更為嚴(yán)重锄奢,這樣便會引發(fā)掉幀美尸、卡頓,而如果把這一步與網(wǎng)絡(luò)異步線程放在一起斟薇,站在用戶角度师坎,最多就是網(wǎng)絡(luò)刷新時(shí)間稍長一點(diǎn)。

數(shù)據(jù)優(yōu)化

分頁拉取遠(yuǎn)端數(shù)據(jù)堪滨,對拉取下來的遠(yuǎn)端數(shù)據(jù)進(jìn)行緩存胯陋,提升二次加載速度;對于新增或者刪除數(shù)據(jù)通過 DiffUtil 來進(jìn)行局部刷新數(shù)據(jù)袱箱,而不是一味地全局刷新數(shù)據(jù)遏乔。

布局優(yōu)化

減少過渡繪制

減少布局層級,可以考慮使用自定義 View 來減少層級发笔,或者更合理地設(shè)置布局來減少層級盟萨,不推薦在 RecyclerView 中使用 ConstraintLayout,有很多開發(fā)者已經(jīng)反映了使用它效果更差了讨,相關(guān)鏈接有:Is ConstraintLayout that slow?捻激、constraintlayout 1.1.1 not work well in listview

減少 xml 文件 inflate 時(shí)間

這里的 xml 文件不僅包括 layout 的 xml前计,還包括 drawable 的 xml胞谭,xml 文件 inflate 出 ItemView 是通過耗時(shí)的 IO 操作,尤其當(dāng) Item 的復(fù)用幾率很低的情況下男杈,隨著 Type 的增多丈屹,這種 inflate 帶來的損耗是相當(dāng)大的,此時(shí)我們可以用代碼去生成布局伶棒,即 new View() 的方式旺垒,只要搞清楚 xml 中每個(gè)節(jié)點(diǎn)的屬性對應(yīng)的 API 即可。

減少 View 對象的創(chuàng)建

一個(gè)稍微復(fù)雜的 Item 會包含大量的 View肤无,而大量的 View 的創(chuàng)建也會消耗大量時(shí)間先蒋,所以要盡可能簡化 ItemView;設(shè)計(jì) ItemType 時(shí)舅锄,對多 ViewType 能夠共用的部分盡量設(shè)計(jì)成自定義 View鞭达,減少 View 的構(gòu)造和嵌套。

其他

其他并不代表不重要皇忿,而是我不能把他們進(jìn)行分類哈畴蹭,其中可能某些操作會對你的 RecyclerView 有很大的優(yōu)化。

  • 升級 RecycleView 版本到 25.1.0 及以上使用 Prefetch 功能鳍烁,可參考 RecyclerView 數(shù)據(jù)預(yù)取叨襟。

  • 如果 Item 高度是固定的話,可以使用 RecyclerView.setHasFixedSize(true); 來避免 requestLayout 浪費(fèi)資源幔荒;

  • 設(shè)置 RecyclerView.addOnScrollListener(listener); 來對滑動(dòng)過程中停止加載的操作糊闽。

  • 如果不要求動(dòng)畫梳玫,可以通過 ((SimpleItemAnimator) rv.getItemAnimator()).setSupportsChangeAnimations(false); 把默認(rèn)動(dòng)畫關(guān)閉來提神效率。

  • TextView 使用 String.toUpperCase 來替代 android:textAllCaps="true"右犹。

  • TextView 使用 StaticLayout 或者 DynamicLayout 的自定義 View 來代替它提澎。

  • 通過重寫 RecyclerView.onViewRecycled(holder) 來回收資源。

  • 通過 RecycleView.setItemViewCacheSize(size); 來加大 RecyclerView 的緩存念链,用空間換時(shí)間來提高滾動(dòng)的流暢性盼忌。

  • 如果多個(gè) RecycledViewAdapter 是一樣的,比如嵌套的 RecyclerView 中存在一樣的 Adapter掂墓,可以通過設(shè)置 RecyclerView.setRecycledViewPool(pool); 來共用一個(gè) RecycledViewPool谦纱。

  • ItemView 設(shè)置監(jiān)聽器,不要對每個(gè) Item 都調(diào)用 addXxListener君编,應(yīng)該大家公用一個(gè) XxListener跨嘉,根據(jù) ID 來進(jìn)行不同的操作,優(yōu)化了對象的頻繁創(chuàng)建帶來的資源消耗吃嘿。

  • 通過 getExtraLayoutSpace 來增加 RecyclerView 預(yù)留的額外空間(顯示范圍之外祠乃,應(yīng)該額外緩存的空間),如下所示:

    new LinearLayoutManager(this) {
        @Override
        protected int getExtraLayoutSpace(RecyclerView.State state) {
            return size;
        }
    };
    
  • 高度盡量設(shè)置為match_parent ,wrap_content的AT_MOST測量模式會使RecyclerView遍歷測量子View的高度,造成不必要的內(nèi)存開銷唠椭。

  • 優(yōu)先使用多布局,如果非要被 ScrollView嵌套的 RecyclerView應(yīng)該再嵌套一層 RelativeLayout避免再某些機(jī)型中導(dǎo)致 RecyclerView顯示不完全跳纳,該設(shè)置 android:nestedScrollingEnabled="false"可以解決 RecyclerView被嵌套后滑動(dòng)不流暢。

    <RelativeLayout
        android:descendantFocusability="blocksDescendants"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <androidx.recyclerview.widget.RecyclerView
            android:nestedScrollingEnabled="false"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </RelativeLayout>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贪嫂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子艾蓝,更是在濱河造成了極大的恐慌力崇,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赢织,死亡現(xiàn)場離奇詭異亮靴,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)于置,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門茧吊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人八毯,你說我怎么就攤上這事搓侄。” “怎么了话速?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵讶踪,是天一觀的道長。 經(jīng)常有香客問我泊交,道長乳讥,這世上最難降的妖魔是什么柱查? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮云石,結(jié)果婚禮上唉工,老公的妹妹穿的比我還像新娘。我一直安慰自己汹忠,他們只是感情好酵紫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著错维,像睡著了一般奖地。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赋焕,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天参歹,我揣著相機(jī)與錄音,去河邊找鬼隆判。 笑死犬庇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的侨嘀。 我是一名探鬼主播臭挽,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼咬腕!你這毒婦竟也來了欢峰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤涨共,失蹤者是張志新(化名)和其女友劉穎纽帖,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體举反,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡懊直,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了火鼻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片室囊。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖魁索,靈堂內(nèi)的尸體忽然破棺而出融撞,到底是詐尸還是另有隱情,我是刑警寧澤蛾默,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布懦铺,位于F島的核電站,受9級特大地震影響支鸡,放射性物質(zhì)發(fā)生泄漏冬念。R本人自食惡果不足惜趁窃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望急前。 院中可真熱鬧醒陆,春花似錦、人聲如沸裆针。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽世吨。三九已至澡刹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間耘婚,已是汗流浹背罢浇。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沐祷,地道東北人嚷闭。 一個(gè)月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像赖临,于是被迫代替她去往敵國和親胞锰。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354