Recyclerview多种场景下的优化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Recyclerview多种场景下的优化相关的知识,希望对你有一定的参考价值。

参考技术A

因为APP设计的原因,Recyclerview是我在android中最常用的组件,我们公司的APP几乎每一个页面都会包含至少一个Recyclerview,本篇文章主要介绍一些我个人在工作中总结、收集的recyclerview优化经验。

1.不要在onBindViewHolder中设置点击事件和耗时操作

Recyclerview的onBindViewHoler主要负责将数据与holder绑定,它在列表滑动时会不停的被调用。如果在onBindViewHolder中设定监听操作,会导致已经的绑定点击事件的view,被重复绑定监听操作。

点击事件的监听可以在onCreateViewHolder中设定。一些会创建新对象的操作,也需要根据实际情况考虑从onBindViewHolder中迁移到onCreateViewHolder。

注意: onBindViewHolder运行在UI线程中,如果进行了耗时操作,会导致页面卡顿。并且onBindViewHolder中只应该进行数据的绑定,而不应该进行数据的处理和计算等操作。

2.Recyclerview嵌套Recyclerview的优化

Recyclerview嵌套Recyclerview最经典的运用就是,一个纵向滑动的列表内部的每个item是一个可以横向滑动的Recyclerview,比如说GooglePlay。

这种情况可以使用LinearLayoutManager.setInitialPrefetchItemCount()设定
横向列表初次显示时可见item的个数。如果横向滑动的View中数据量很少,并且不需要横向刷新时,也可以考虑使用HorizontalScrollView实现。

关于这个API的官方文档翻译如下:

如果将此值设置为大于此视图中可见的视图数可能会导致不必要的绑定工作,并且会增加创建和活动使用的视图数。

3.多个RecycerView共用RecycledViewPool

在大多数APP中都有这样一种场景,一个ViewPager中包含多个Fragment,而Fragment中主体是Recyclerview,并且Recyclerview中item view的布局是相同的。例如 微博等

这种情况下,Recyclerview可以设定统一的缓存池用来提高性能。

新建缓存池:

设定缓存池:

4.精确的更新数据使用DiffUtil

在Recyclerview中提供了多种数据数据刷新方式

虽然有了这些刷新方式,但是实际开发中,存在这样一种情况,新数据集与旧数据集仅有一部分数据存在差异。

例如:刷新一个联系人列表,联系人列表中部分联系人的头像有变化,但是姓名和手机号码等信息未发生变化。这种情况以往都是使用notifyDataChanged方法刷新全部数据,但是刷新全部数据的会导致整个布局重绘,Recyclerview中针对这种情况还提供了另一种粒度更小的刷新方式 DiffUti

这里不打算去讲DiffUtil的具体用法,只需要记住DiffUtil的使用场景即可: 列表中存在多个Item的数据需要刷新,但是新数据集与旧数据集存在重复的情况

5.灵活设定setHasFixedSize
在Recyclerview中使用以下方法时,会触发requestLayout()

requestLayout()会重新计算item的大小,如果item的布局文件已经将宽高设为固定大小,可以设定setHasFixedSize(true),来避免Recyclerview重新计算item的大小。

6.优化Item的布局
布局优化是个老生长谈的问题,本质上就是减少嵌套,ConstraintLayout是google推出的一个用于减少布局嵌套的新layout,但是在Recyclerview中使用ConstraintLayout会导致cpu使用率上升,暂时不推荐使用,不过ConstraintLayout 2.0版本已经进入beta测试,期待后续会有优化。

7.数据非常少时,使用ListView
不知道你有没有考虑过这样的问题,RecyclerView用已经如此强大,用得人也越来越多,为什么最新的Android系统中ListView依然没有被标注为"过时"。
RecyclerView重新设计了缓存机制,新的缓存机制更加强大,更适合处理大量数据的显示,但是这种缓存机制会占据更多的内存,当一个列表页面实际数据项非常少的时候,ListView往往比RecyclerView更合适。

以上是关于Recyclerview多种场景下的优化的主要内容,如果未能解决你的问题,请参考以下文章

RecyclerView 挤压子项宽度

如何在 RecyclerView 中实现 StartActivityForResult

Android教程2020 - RecyclerView显示多种item

片段内的 RecyclerView 的 Kotlin OnItemClickListener

RecyclerView 在 BottomSheetFragment 中隐藏其下方的项目

为啥 recyclerview 的 searchview 不起作用?