recyclerview

recyclerview 吸顶效果,复用,自定义layoutManager

自定义NestedScrollView,监听setOnScrollChangeListener,
判断scrollY值,当其达到第一个child的高度时,
调用recyclerview fling方法
onNestedPreScroll方法
判断dy大于0,ScrollY小于topView高度时,调用scrollBy进行滚动

缓存:

ViewHolder在首先会缓存在 mCachedViews 中,当超过了个数(比如默认为2), 就会添加到 RecycledViewPool 中
按照Type来查找ViewHolder,每个Type默认最多缓存5个

RecyclerView 在获取 ViewHolder 时按四级缓存的顺序查找,如果没找到就创建。
其中只有 RecycledViewPool 找到时才会调用 bindViewHolder,其它缓存直接返回 ViewHolder 。

RecyclerView 最多可以缓存 N(屏幕最多可显示的item数) + 2 (屏幕外的缓存) + 5*M (M代表M个ViewType,缓存池的缓存)

在这里插入图片描述
mAttachedScrap:
未与RecyclerView分离的ViewHolder列表,如果仍依赖于 RecyclerView (比如已经滑动出可视范围,但还没有被移除掉),但已经被标记移除的 ItemView 集合会被添加到 mAttachedScrap 中
按照id和position来查找ViewHolder

mChangedScrap:
表示数据已经改变的viewHolder列表,存储 notifXXX 方法时需要改变的 ViewHolder
匹配机制按照position和id进行匹配

mCachedViews:
缓存ViewHolder,主要用于解决 RecyclerView 滑动抖动时的情况,还有用于保存Prefetch的ViewHoder
最大的数量为:mViewCacheMax = mRequestedCacheMax + extraCache(extraCache是由prefetch的时候计算出来的)

mViewCacheExtension:
开发者可自定义的一层缓存,是虚拟类ViewCacheExtension的一个实例,开发者可实现方法
getViewForPositionAndType(Recycler recycler, int position, int type)来实现自己的缓存。

ViewHolder缓存池
mCachedViews 存不下 ViewHolder 时,就会把 ViewHolder 存入 RecyclerViewPool 中。
1、按照 Type 来查找 ViewHolder1
2、每个Type默认最多缓存5个

mCacheViews满了以后,再进来的会存入mCacheViews,然后移除mCacheViews里面的一个到pool中。

Scrap:屏幕内的缓存数据
Cache
ViewCacheExtension
RecycledViewPool

如果调用 notifyDataSetChanged,每个 itemView 没有稳定的 id 的话,
RecyclerView 不知道接下来会发生什么,也不知道哪些改变,
它假设所有都改变了,会将每一个 ViewHolder 设置成无效并且放到缓存池 Pool 中,
如果我们仅是把屏幕上的第四条 itemView 移到第六条的位置,屏幕上所有itemView都会重新 layout 一遍,
这样只能从缓存池 RecycledViewPool 池中取缓存的 ViewHolder ,如果不够时,需要重新 create ViewHolder

设置 Id,每一个 itemView 都有一个唯一的id来标识,通过 getItemId() 来获取这个唯一标识id,
当然我们不能用 position 来标识,因为 itemView 会复用,位置会乱序。
当调用 notifyDataSetChanged() 方法时,ViewHolder 会进入上面的一级缓存 mAttachedScrap 中,而不是进入缓存池 pool 中
这样的好处:
1、不会存在缓存池 pool 满的问题,不需要重新 createViewHolder;
2、不需要重新 bindView。

当Item的高度如是固定的,设置这个属性为true可以提高性能
尤其是当RecyclerView有条目插入、删除时性能提升更明显。
RecyclerView在条目数量改变,会重新测量、布局各个item,
如果设置了setHasFixedSize(true),由于item的宽高都是固定的,adapter的内容改变时,RecyclerView不会整个布局都重绘。
具体可用以下伪代码表示:
void onItemsInsertedOrRemoved() {
if (hasFixedSize) layoutChildren();
else requestLayout();
}

尽量避免繁琐的操作和循环创建对象。例如创建 OnClickListener,可以全局创建一个。
同时onBindViewHolder调用次数会多于onCreateViewHolder的次数
如从RecyclerViewPool缓存池中取到的View都需要重新bindView,所以我们可以把监听放到CreateView中进行。

fragment原理,懒加载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值