高级UIAndroid性能优化与实践

Recyclerview多种场景下的优化

2019-06-17  本文已影响110人  林栩link

前言

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

正文

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

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

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

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


Google play 截图

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

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

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

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


微博 截图

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

新建缓存池:

RecyclerView.RecycledViewPool viewPool=new RecyclerView.RecycledViewPool();

设定缓存池:

recyclerView.setRecycledViewPool(viewPool);

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

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

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

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

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

上一篇 下一篇

猜你喜欢

热点阅读