国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

RecyclerView配合DiffUtil,好用到飛

開發 開發工具
DIffUtils 是 Support-v7:24:2.0 中,更新的工具類。因為已經更新了一段時間了,也不好說是最新更新的。

 [[200515]]

一、前言

DIffUtils 是 Support-v7:24:2.0 中,更新的工具類。因為已經更新了一段時間了,也不好說是***更新的。

它主要是為了配合 RecyclerView 使用,通過比對新、舊兩個數據集的差異,生成舊數據到新數據的最小變動,然后對有變動的數據項,進行局部刷新。

接下來就 DiffUtil 的使用細節,進行一個詳細的講解,希望一篇文章就完全理解 DiffUtil。

二、為什么會有DiffUtil

RecyclerView 自從被發布以來,一直被說成是 ListView、GridView 等一系列列表控件的***替代品。并且它本身使用起來也非常的好用,布局切換方便、自帶 ViewHolder 、局部更新并且可帶更新動畫等等。

局部更新、并且可以很方便的設置更新動畫這一點,是 RecyclerView 一個不錯的亮點。它為此提供了對應的方法:

  • adapter.notifyItemChange()
  • adapter.notifyItemInserted()
  • adapter.notifyItemRemoved()
  • adapter.notifyItemMoved()

以上方法都是為了對數據集中,單一項進行操作,并且為了操作連續的數據集的變動,還提供了對應的 notifyRangeXxx() 方法。

雖然 RecyclerView 提供的局部更新的方法,看似非常的好用,但是實際上,其實并沒有什么用。

在實際開發中,最方便的做法就是無腦調用 notifyDataSetChanged(),用于更新 Adapter 的數據集。

雖然 notifyDataSetChanged() 有一些缺點:

  • 不會觸發 RecyclerView 的局部更新的動畫。
  • 性能低,會刷新整個 RecyclerView 可視區域。

但是真有需要頻繁刷新,前后兩個數據集的場景。

方案一:使用一個 notifyDataSetChanged() 方法。

方案二:自己寫一個數據集比對方法,然后去計算他們的差值,***調用對應的方法更新到 RecyclerView 中去。

我這么懶,如果不是必要,當然是會選 方案一 了。畢竟和之前 ListView 的時候,也沒有更差了。

Google 顯然也發現了這個問題,所以 DiffUtil 被發布了。

三、介紹DiffUtil

就像前面說的,DiffUtil 就是為了解決這個痛點的。它能很方便的對兩個數據集之間進行比對,然后計算出變動情況,配合 RecyclerView.Adapter ,可以自動根據變動情況,調用 Adapter 的對應方法。

當然,DiffUtil 不僅只能配合 RecyclerView 使用,它實際上可以單獨用于比對兩個數據集,然后如何操作是可以定制的,那么在什么場景下使用,就全憑我們自己發揮了。

DiffUtil 在使用起來,主要需要關注幾個類:

  • DiffUtil.Callback:具體用于限定數據集比對規則。
  • DiffUtil.DiffResult:比對數據集之后,返回的差異結果。

1、DiffUtil.Callback

DiffUtil.Callback 主要就是為了限定兩個數據集中,子項的比對規則。畢竟開發者面對的數據結構多種多樣,既然沒法做一套通用的內容比對方式,那么就將比對的規則,交還給開發者來實現即可。

在 Callback 中,其實只需要實現 4 個方法:

  • getOldListSize():舊數據集的長度。
  • getNewListSize():新數據集的長度
  • areItemsTheSame():判斷是否是同一個Item。
  • areContentsTheSame():如果是通一個Item,此方法用于判斷是否同一個 Item 的內容也相同。

前兩個是獲取數據集長度的方法,這沒什么好說的。但是后兩個方法,主要是為了對應多布局的情況產生的,也就是存在多個 viewType 和多個 ViewHodler 的情況。首先需要使用 areItemsTheSame() 方法比對是否來自同一個 viewType(也就是同一個 ViewHolder ) ,然后再通過 areContentsTheSame() 方法比對其內容是否也相等。

其實 Callback 還有一個 getChangePayload() 的方法,它可以在 ViewType 相同,但是內容不相同的時候,用 payLoad 記錄需要在這個 ViewHolder 中,具體需要更新的View。

areItemsTheSame()、areContentsTheSame()、getChangePayload() 分別代表了不同量級的刷新。

首先會通過 areItemsTheSame() 判斷當前 position 下,ViewType 是否一致,如果不一致就表明當前 position 下,從數據到 UI 結構上全部變化了,那么就不關心內容,直接更新就好了。如果一致的話,那么其實 View 是可以復用的,就還需要再通過 areContentsTheSame() 方法判斷其內容是否一致,如果一致,則表示是同一條數據,不需要做額外的操作。但是一旦不一致,則還會調用 getChangePayload() 來標記到底是哪個地方的不一樣,最終標記需要更新的地方,最終返回給 DiffResult 。

當然,對性能要是要求沒那么高的情況下,是可以不使用 getChangedPayload() 方法的。

2、DiffUtil.DiffResult

DiffUtil.DiffResult 其實就是 DiffUtil 通過 DiffUtil.Callback 計算出來,兩個數據集的差異。它是可以直接使用在 RecyclerView 上的。如果有必要,也是可以通過實現 ListUpdateCallback 接口,來比對這些差異的。

3、使用DiffUtil

介紹了 Callback 和 DiffResult 之后,其實就可以正常使用 DiffUtil 來進行數據集的比對了。

在這個過程中,其實真的很簡單,只需要調用兩個方法:

  1. DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffCallBack(oldDatas, newDatas), true);  
  2. diffResult.dispatchUpdatesTo(mAdapter); 

calculateDiff 方法主要是用于通過一個具體的 DiffUtils.Callback 實現對象,來計算出兩個數據集差異的結果,得到 DiffUtil.DiffResult 。

而 calculateDiff 的另外一個參數,用于標記是否需要檢測 Item 的移動。

DiffUtil 使用的是 Eugene Myers 的差別算法,這個算法本身是不檢查元素的移動的。也就是說,有元素的移動它也只是會先標記為刪除,然后再標記插入。而如果需要計算元素的移動,它實際上也是在通過 Eugene Myers 算法比對之后,再進行一次移動檢查。所以,如果集合本身已經排序過了,可以不進行移動的檢查。

而 dispatchUpdatesTo() 就是將這個數據集差異的結果,通過 Adapter 更新到 RecyclerView 上面。

實際上 dispatchUpdatesTo(Adapter) ,也是使用的 ListUpdateCallback 這個接口,在其中獲得差異,然后調用 Adapter 的對應方法。

四、上例子

既然已經說清楚了,那么我們開始上例子了。

功能很簡單,有四個數據集,使用 RecyclerView 承載,然后有一個按鈕,用于輪換的切換數據集。

1、實現 DiffUtil.Callback

為了簡單,RecyclerView 中使用單一 ViewType ,并且使用一個 TextView 承載一個 字符串來顯示。

那么我們開始實現 Callback:

 

2、切換數據集

既然已經有了 DiffUtil.Callback 的實現之后,我們就需要對切換數據集的點擊事件進行處理了。

3、實現效果

關鍵代碼已經貼出來了,其實非常的簡單,最終運行的效果如下:

五、DiffUtil 效率問題

既然 DiffUtil 非常的好用,并且內部也實現了一套算法,但是我們也需要關心它的效率問題。

根據 Google 官方文檔中給出的例子,在 Nexus 5X M 系統上,DiffUtil 的效率問題,給出了一些參考的數據:

可以看到,實際上,DiffUtil 的算法把效率問題解決的非常的好。在開啟計算移動的情況下,1000 條數據中有 200 個修改,平均值也只有 13.54 ms ,基本上都是毫秒級的。

Google 官方同時也指出,如果是對大數據集的比對,***是方在子線程中去完成計算,也就是其實是存在堵塞 UI 的情況的。所以如果你遇見了使用 DiffUtil 之后,每次刷新有卡頓的情況,可以考慮是否數據集太大,是否應該在子線程中完成計算。

六、結語

DiffUtil 已經介紹完了,如果覺得本文對你有幫助。都看到這里了,點個贊再走吧。

 

【本文為51CTO專欄作者“張旸”的原創稿件,轉載請通過微信公眾號聯系作者獲取授權】

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2025-04-18 08:24:22

2023-12-12 13:49:00

差量算法Myers

2020-08-23 09:30:32

jupyter lab插件開發

2021-07-19 15:47:45

Python編程語言代碼

2022-04-12 08:43:21

Python內置模塊

2020-09-20 22:04:11

Windows 工具系統

2021-10-06 15:58:26

Python工具代碼

2018-07-10 09:36:25

2012-08-10 10:10:05

視頻會議飛視美

2021-11-15 10:02:16

Python命令技巧

2023-04-26 00:34:36

Python技巧程序員

2022-03-29 18:18:07

Kubernetes框架

2022-02-24 10:48:01

Pycharm插件

2024-07-19 10:31:15

2022-07-17 11:45:39

微服務架構

2020-10-14 18:53:14

Python編程語言

2021-04-12 11:05:09

Windows微軟軟件

2022-01-13 11:50:57

Python技巧代碼

2021-11-26 10:36:36

瀏覽器插件谷歌

2019-11-24 23:12:30

Vim插件編輯器編程語言
點贊
收藏

51CTO技術棧公眾號

国产精选在线| 操人视频在线观看欧美| 欧美大片网站| 首页亚洲中字| 国产盗摄精品一区二区三区在线 | 一区二区免费在线视频| 91av资源网| 激情aⅴ欧美一区二区欲海潮| 亚洲欧洲另类国产综合| 日日摸夜夜添一区| 国产尤物99| 日本三级电影网| 国产精品色婷婷在线观看| 久久午夜精品一区二区| 欧美日韩国产页| 欧美一区二三区| 激情婷婷综合网| 成年美女黄网站色大片不卡| 日产国产高清一区二区三区| 日本久久电影网| 久久偷看各类wc女厕嘘嘘偷窃 | 日本韩国一区二区三区| 欧美久久久久久久久久| 欧美大片第1页| 91精彩视频在线观看| 国产乱淫av一区二区三区| 国产精品第七十二页| 亚洲一区二区av| 日韩国产精品亚洲а∨天堂免| 爱情岛论坛成人| 精品一区免费av| 免费观看成人在线| 亚洲欧美怡红院| 四虎成人精品一区二区免费网站| 亚洲护士老师的毛茸茸最新章节| 亚洲色图综合网| 福利在线一区二区| 日本中文字幕一区二区视频 | 国产亚洲综合在线| 亚洲欧洲一区二区三区久久| 欧洲乱码伦视频免费| 国产亚洲视频在线观看| 午夜国产视频| 亚洲欧洲精品一区二区三区不卡 | 91在线观看欧美日韩| 国内精品久久久久久久影视蜜臀| 亚洲一区免费| 日韩精品中文字幕一区| av网站在线免费观看| 欧美在线视频在线播放完整版免费观看 | 亚洲图片你懂的| www.三区| 中文字幕不卡在线观看| 91xxx视频| 蜜臀久久99精品久久久久久9| 国产精品专区h在线观看| 97久久亚洲| 国产精品三级美女白浆呻吟| 欧美成人家庭影院| 中文字幕久久一区| 99re在线视频这里只有精品| 黄色网址在线免费看| 欧美在线观看你懂的| 美女被人操视频在线观看| 香蕉av福利精品导航| 羞羞免费视频网站| 亚洲精品一二三四区| 国产精品区在线| 一区二区三区欧美| 亚洲免费视频一区二区三区| 亚洲欧美日韩区| 亚洲www视频| 亚洲欧美日本视频在线观看| 国产盗摄在线视频网站| 欧美激情一区二区三区成人| 亚洲激情婷婷| 欧美床上激情在线观看| 日韩免费电影一区| 99a精品视频在线观看| 欧美凹凸一区二区三区视频| 亚洲电影一区二区三区| 欧美成人网在线| 电影在线一区| 久久久久久**毛片大全| av动漫在线免费观看| 肉色丝袜一区二区| 波多野结衣久草一区| 99久久综合狠狠综合久久aⅴ| 久久精品99国产精品酒店日本| 欧美日韩精品免费观看视完整| 4438成人网| av一区在线| 97在线视频免费看| 猫咪成人在线观看| 97超级在线观看免费高清完整版电视剧| 久久视频国产| 国产日韩欧美中文在线播放| 欧美日韩视频| 欧美美女黄色网| 久久伊99综合婷婷久久伊| 丁香花在线影院观看在线播放| 91丝袜美腿高跟国产极品老师 | 亚洲成人av观看| 久久色精品视频| 欧美经典一区二区| 国产超碰在线观看| 国产精品一区二区你懂得| 麻豆国产精品官网| 狠狠热免费视频| 国产精品v片在线观看不卡| 日韩欧美在线视频观看| 在线毛片观看| 国产精品一区二区久久精品| 欧美情侣在线播放| www欧美成人18+| 在线中文字幕第一区| 九一免费在线观看| 韩国精品久久久999| 久久66热re国产| 窝窝社区一区二区| 99thz桃花论族在线播放| 日韩美女激情视频| 国产精品18久久久久久久久久久久| 久久影院一区二区三区| 丝袜足脚交91精品| 亚洲午夜免费视频| 99久久这里有精品| 全部免费毛片在线播放网站| 成人精品视频一区二区三区尤物| 免费人成黄页在线观看忧物| 亚洲91精品在线| 国产欧美一区二区色老头| 噜噜噜在线观看播放视频| 久久久久久免费看| 国产伦精品一区二区三区| 97超碰蝌蚪网人人做人人爽| 伊人久久五月天| 国产精品久久久久久久免费软件| 99精品国产高清一区二区麻豆| 另类激情视频| 亚洲国产精品精华素| 精品国产第一页| 欧美无砖专区一中文字| 亚洲男同1069视频| 1024精品合集| 亚洲综合在线五月| 国产精品电影一区二区| 国产精品自在线拍| 在线看的黄色网址| 午夜精品久久久久久久男人的天堂| 中文字幕精品网| 2020国产精品自拍| 国产亚洲综合av| 一区二区三区在线视频免费 | 2019最新中文字幕| 国产成人一区二| 精品久久在线播放| 91精品99| 菠萝菠萝蜜在线观看| 奇米精品在线| 精品激情国产视频| 欧美极品少妇xxxxⅹ免费视频 | 亚洲二区在线视频| 日韩欧美中文字幕精品| 国产91在线看| 国产a久久精品一区二区三区| 最新在线地址| 日韩欧美第二区在线观看| 在线电影av不卡网址| 久久久黄色av| 亚洲综合日韩在线| 日韩国产小视频| 国产v亚洲v天堂无码久久久| 国产美女精品久久久| 青青草成人免费在线视频| 国产精品成人一区二区三区吃奶| 成人免费视频观看视频| 一区国产精品视频| 国产精品视频资源| 国内少妇毛片视频| 国产视频一二区| 超薄肉色丝袜足j调教99| hbad中文字幕| a毛片不卡免费看片| 国产精品国内免费一区二区三区| 久久aⅴ国产欧美74aaa| 色综合久久久久久久| 国产精品三级视频| 日本女人一区二区三区| 性欧美大战久久久久久久久| 久久高清视频免费| 中国女人做爰视频| 黄色网页在线免费看| 91嫩草在线播放| 日韩精品视频久久| 成人黄色动漫| 亚洲在线成人| 欧美日本在线看| 在线观看亚洲专区| 在线亚洲人成电影网站色www|