RecyclerView 的核心知识(干货~~)

19 篇文章 0 订阅

RecyclerView 的核心知识

说道 RecyclerView 就不得不想起他的 前辈listView,RecyclerView 的 出现解决了ListView的一些问题。下面就说一下二者在缓存上面的区别。

ListView 的缓存

它分为两层缓存

1 Active View (在屏幕内部,可视部分的缓存)

2 Scrap View (滑出屏幕部分,不可见部分的缓存)

RecycleBean 会先去 1 里面找,没有的话就会去2里面找,还没有的话,就会在getView的 ContentView中返回null,此时就需要开发者自己去创建 View了 并且去findviewbyid()了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-78CHkKXq-1599029966398)(https://i.imgur.com/0M17an0.png)]

下图更清楚的说明了 两种的缓存作用的位置。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KceEmjaO-1599029966400)(https://i.imgur.com/UawH6F1.png)]

RecyclerView 的缓存

图中已经做了标注解释

ps:这里的 Scrap 相当于 ListView 的可视部分缓存
    在 1,2中 都是通过position 去找缓存了,都是干净的数据可以拿来直接用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pWdlatSt-1599029966402)(https://i.imgur.com/27bYwGC.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pNdEyBa5-1599029966403)(https://i.imgur.com/px6BWtw.png)]

列表中 item / 广告的 impression 统计
  • ListView 可以通过 getView 准确的知道 广告浏览次数。(因为ListView的item 从不可见到可见,肯定是调用getView)

  • RecyclerView 通过 onBindViewHolder()统计会有问题!(自身的缓存机制,会不走 onBindViewHolder()方法)。

  • 要通过 onViewAttachedToWindow()方法统计 (每次进入屏幕都会调用这个方法)。

你可能不知道的 RecyclerView 性能优化策略

1 设置点击事件优化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7iRYTYkM-1599029966404)(https://i.imgur.com/OEYrJ8Z.png)]

我们通常会将 item中 view的点击事件设置在 onBindViewHodler()方法中,带式这样做会导致我么每次刷新的时候都会 new View.onClicklestener,浪费了性能。所以写在onCreateViewHolder()中比较好

2 LinearLayoutManager.setlnitialPrefetchltemCount() “横向滑动时候的预加载个数” 详情看下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r901AacQ-1599029966404)(https://i.imgur.com/7okr48y.png)]

3 RecyclerView.setHasFixedSize();

设置为true的时,在内容发生改变时,会走layoutChildren()局部更新,requestLayout() 是全部更新—能省点是点,

4 RecycledViewPool 共用。

上面提到 RecycledViewPool 会根据viewType缓存,那么如果我的几个RV 同时可能都用到一些相同的 viewType布局 ,那么就可以共用一个RecyclerViewPool,下面是代码例子(非实际情况)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gkcfEPe1-1599029966404)(https://i.imgur.com/bzslJkH.png)]

具体场景一个TabLayout 有多个标题 每个标题对应一个 Rv

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mUsqRPEU-1599029966404)(https://i.imgur.com/xmvnNpH.png)]

DiffUtil (稍难) 计算一个集合更新到另一个集合的最小变化。

使用它的原因

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qKoc8QLO-1599029966405)(https://i.imgur.com/roMYsJu.png)]

先看一下 DiffUtil.Callback抽象类,他有5个方法

ps:它是给系统用的Callback,我需要在这5个方法中做计算,然后系统会根据这5个方法做 “动态规划”(算法的一种)。

  • getOldListSize () 旧集合
  • getNewListSize () 新集合
  • areItemsTheSame() 判断是不是一个对象(并不是对比内存地址,而是对比关键参数,比如 User的 身份证号。。。)
  • areContentSTheSame() 在上一个方法返回 true时 去对比User内部的成员 是否一致。
  • getChangePayload 在上一个方法返回false是,说明有变化,那么就把变化的部分存起来。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XKZCitAK-1599029966406)(https://i.imgur.com/iPmpXLJ.png)]

具体代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pLZg5UPn-1599029966406)(https://i.imgur.com/asGwTlc.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ih258qge-1599029966406)(https://i.imgur.com/XpL8gDY.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dM1UJxwp-1599029966407)(https://i.imgur.com/fUidKM3.png)]

图中的this,传adapter的引用就好了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mLKEcRrz-1599029966407)(https://i.imgur.com/8juJ60U.png)]

当我们使用diff的时候就要重载 onBindViewHodler 三个参数的方法 用到里面的payloads参数

这样就完成了增量更新

用三种方法讲diff的计算去异步进行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ER92BaVN-1599029966408)(https://i.imgur.com/ICWiAV0.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7RbBERPg-1599029966408)(https://i.imgur.com/z1cRPmY.png)]

ItemDecoration 做分隔线太麻烦?

  • 1 想要将 Divider 画在item外边,需要offset 做偏移,就调用onDraw() 方法;
  • 2 想要将 Divider 画在item里边 ,就调用 onDrawOver()方法;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8GO1RtZq-1599029966408)(https://i.imgur.com/W53LHAp.png)]

ItemDecoration 还能干什么?
  • 1 分隔线
  • 2 高亮
  • 3 分组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7O3MvD8R-1599029966409)(https://i.imgur.com/8QIIWhH.png)]

高亮

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FDF2Td14-1599029966409)(https://i.imgur.com/cPvLS66.png)]

ItemDecoration 是可以做效果叠加的 扩展性做的很好 所以可以做各种各样的效果 装饰!~

//因为这里是 add 而不是 set
DividerItemDecoration decoration = new DividerItemDecoration(getApplicationContext(), VERTICAL);

recyclerView.addItemDecoration(decoration);

###Recycler的更多知识请关注
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vzlWADOB-1599029966410)(https://i.imgur.com/eziAxRC.png)]

就先到这里,后面会分享更多的 Android 开发内容 感谢浏览!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值