Recyclerview 复用之headview优化

版本:support-v7 25.3.1

发现问题

在对 性能优化-首页CPU占用优化 调研时发现,首页的OnCreateViewHolder存在高频次调用的情况,而常见的开源列表组件不存在此问题。

遂针对此问题,对recyclerview的复用机制进行分析。

缓存集合

1 mChangedScrap 表示数据已经改变的ViewHolder集合

image.png

2 mAttachedScrap 与RecyclerView尚未分离的ViewHolder集合

3 mCachedViews ViewHolder缓存集合,默认为2。

4 mViewCacheExtension 开发者可自定义集合

5 mRecyclerPool ViewHolder缓存池。 被用来做下一级的缓存。默认最大为五个。

image.png

缓存复用流程

从onCreateViewHolder的调用开始看

image.png

tryGetViewHolderForPositionByDeadline方法,也是复用机制的重点。

这是一个自带过期时间的view复用函数,返回的对象如果时间不允许,那么可能会是null或者未绑定的。

dryRun 控制使用完缓存之后,是否需要从缓存中删除。

image.png

1 从被改变的废料中获取组件

如果这里是一个改变了的废料,那么使用getChangedScrapViewForPosition函数去获取。

// 0) If there is a changed scrap, try to find from there

image.png

来看具体的实现方法,

ViewHolder getChangedScrapViewForPosition(int position)

image.png

2 根据 position 从已经改变的废料集合中搜索缓存

如果成功,则打回。 第二步 根据id查询废料缓存。

3 从隐藏或者缓存的组件集合中获取 根据posotion

getScrapOrHiddenOrCachedHolderForPosition // 1) Find by position from scrap/hidden list/cache

image.png

这里做了两件事情,第一个从缓存列表中获取holder,然后在验证其有效性。

其实这里的getScrapOrHiddenOrCachedHolderForPosition 方法是缓存的重点功能实现。

image.png

4 从隐藏和缓存组件集合中获取,根据ids

image.png

从自定义的扩展中读取缓存

略,项目中未使用此功能。

从RecyclerPool读取缓存

这级别的是一个根据view type 进行缓存的SparseArray对象。

image.png

收获

1) 加深了对RecyclerView 缓存机制的理解

2) 问题定位: 

项目中的headview的高度比itemview的高度,高出很多倍。 所以在 当head view被回收的时候,缓存中的itemview数量不足以复用,导致多次调用手动实例化方法。

3) 优化建议:

使用了headview的情况下,建议head view的高度不要比正常的item高度超过太多。 

这样可以使item的使用完全可以通过缓存消化,避免频繁的手动实例布局文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RecyclerView复用错乱问题是因为它的使用方式不正确所导致的。复用错乱是指在滑动RecyclerView时,列表项的数据与视图不匹配,在屏幕上显示的数据混乱或重复。 造成这个问题的常见原因有以下几点: 1. 数据源更新不及时:当数据源发生变化时,需要及时更新适配器的数据集。如果没有正确地处理数据源的变化,就会导致RecyclerView中的视图与数据不匹配。 2. 没有正确实现ViewHolder模式:RecyclerView通过重用ViewHolder来提高性能。如果没有正确实现ViewHolder模式,就会导致视图复用时数据混乱。正确的做法是在ViewHolder中设置视图的数据,而不是在绑定ViewHolder时修改视图的数据。 3. 使用了错误的布局管理器:布局管理器决定了RecyclerView中列表项的排列方式。如果使用了错误或不合适的布局管理器,就会导致列表项的位置混乱或错乱。 解决RecyclerView复用错乱问题的方法有以下几点: 1. 在数据源发生变化时,及时更新适配器的数据集,并调用适配器的notifyDataSetChanged方法,通知RecyclerView进行视图更新。 2. 确保正确实现ViewHolder模式,在ViewHolder中正确地设置视图的数据。 3. 注意选择合适的布局管理器,确保列表项的位置正确排列。 4. 可以使用一些开源库或框架,如DiffUtil或DataBinding等,来简化数据源更新和视图更新的过程。 总结起来,解决RecyclerView复用错乱问题的关键是正确处理数据源的更新、正确实现ViewHolder模式、选择合适的布局管理器,并注意使用相关的开源库或框架来简化开发过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值