RecyclerView相比ListView已经有局部的定向更新,但是如果涉及到大量的数据的更新,比如执行刷新操作后,正常需要替换所有的数据,然后调用
adapter.notifyDataSetChanged()
进行全量更新;但是可能出现界面闪烁;另外大多数时候有一部分数据其实没有变化,理论上并不需要重新绑定;
DiffUtil使用场景
- 存在更新前和更新后的两个数据集合可以用来对比,如果直接操作Adapter.Data则没法使用;
- 避免更新页面闪烁
- 部分数据刷新
- 可以覆写
areContentsTheSame、areItemsTheSame
两个方法,比如areContentsTheSame
需要比较内容,可能需要JavaBean重写equals方法
性能对比
The test list is composed of random UUID Strings and the tests are run on Nexus 5X with M
- 100 items and 10 modifications: avg: 0.39 ms, median: 0.35 ms
- 100 items and 100 modifications: 3.82 ms, median: 3.75 ms
- 100 items and 100 modifications without moves: 2.09 ms, median: 2.06 ms
- 1000 items and 50 modifications: avg: 4.67 ms, median: 4.59 ms
- 1000 items and 50 modifications without moves: avg: 3.59 ms, median: 3.50 ms
- 1000 items and 200 modifications: 27.07 ms, median: 26.92 ms
- 1000 items and 200 modifications without moves: 13.54 ms, median: 13.36 ms
用例
class RecyclerViewActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_recyclerview)
supportActionBar!!.title = "RecyclerView"
add.setOnClickListener {
val data = ArrayList<User>()
for (i in 42..100) {
data.add(User("name $i", i))
}
val calculateDiff = DiffUtil.calculateDiff