Recycleview四级缓存

  • mAttachedScrap(屏幕内),用于屏幕内itemview快速重用,不需要重新createView和bindView
  • mCacheViews(屏幕外),保存最近移出屏幕的ViewHolder,包含数据和position信息,复用时必须是相同位置的ViewHolder才能复用,应用场景在那些需要来回滑动的列表中,当往回滑动时,能直接复用ViewHolder数据,不需要重新bindView。
  • mViewCacheExtension(自定义缓存),不直接使用,需要用户自定义实现,默认不实现。
  • mRecyclerPool(缓存池),当cacheView满了后或者adapter被更换,将cacheView中移出的ViewHolder放到Pool中,放之前会把ViewHolder数据清除掉,所以复用时需要重新bindView。

如果多个RecyclerView之间用setRecycledViewPool(RecycledViewPool)设置同一个RecycledViewPool,他们就可以共享Item。其实RecycledViewPool的内部维护了一个Map,里面以不同的viewType为Key存储了各自对应的ViewHolder集合。可以通过提供的方法来修改内部缓存的Viewholder。

四级缓存按照顺序需要依次读取。所以完整缓存流程是:

保存缓存流程:

  • 插入或是删除itemView时,先把屏幕内的ViewHolder保存至AttachedScrap中
  • 滑动屏幕的时候,先消失的itemview会保存到CacheView,CacheView大小默认是2,超过数量的话按照先入先出原则,移出头部的itemview保存到RecyclerPool缓存池(如果有自定义缓存就会保存到自定义缓存里),RecyclerPool缓存池会按照itemview的itemtype进行保存,每个itemType缓存个数为5个,超过就会被回收。

获取缓存流程:

  • AttachedScrap中获取,通过pos匹配holder——>获取失败,从CacheView中获取,也是通过pos获取holder缓存——>获取失败,从自定义缓存中获取缓存——>获取失败,从mRecyclerPool中获取——>获取失败,重新创建viewholder——createViewHolder并bindview。

预取功能(Prefetch)

这个功能是rv在版本25之后自带的,LinearLayoutManager的setInitialItemPrefetchCount()我们可以手动控制该功能。

功能:预取接下来可能要显示的item,在下一帧到来之前提前处理完数据,然后将得到的itemholder缓存起来,等到真正要使用的时候直接从缓存取出来即可。

刷新方法:

  • notifyDataSetChanged(),刷新全部可见的item。
  • notifyItemChanged(int)、notifyItemChanged(int position, @Nullable Object payload),刷新指定item。
  • notifyItemRangeChanged(int,int),从指定位置开始刷新指定个item。
  • notifyItemInserted(int)、notifyItemMoved(int)、notifyItemRemoved(int)。插入、移动一个并自动刷新。
  • notifyItemChanged(int, Object),局部刷新。

notifyItemChanged(int position, @Nullable Object payload)

        @Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull List<Object> payloads) {Item item = mData.get(position);if (payloads.isEmpty()) {super.onBindViewHolder(holder, position, payloads);} else {holder.itemView.setSelected(item.isSelected());}}

可以重写RecyclerView的另一个onBindViewHolder方法,在里面添加payloads的判空,可以作为标记(如上),也可以用来传值。

优化:

  • 设置RecyclerView.addOnScrollListener();来在滑动过程中停止加载的操作。
  • 使用diffutil进行局部刷新,少用全局刷新
  • bindViewHolder方法是在UI线程进行的,此方法不能耗时操作,不然将会影响滑动流畅性。
  • item高度是固定的话,可以使用RecyclerView.setHasFixedSize(true);来避免requestLayout浪费资源。3
  • 对 ItemView 设置监听器,不要对每个 Item 都new 一个 Listener,应该大家公用一个 Listener,根据 ID 来进行不同的操作,优化了对象的频繁创建带来的资源消耗。

Recylerview刷新图片闪烁:

@Override
public long getItemId(int position) {return position;
}mAdapter.setHasStableIds(true);

setHasStableIds:数据集中的每一项是否设置有一个唯一标识。

getItemId:给位置的项一个ID。

两个方法配合使用,相当于给ImageView加了一个tag,tag不变的话,不用重新加载图片的 ImageView 不重新加载。

也可以使用局部刷新来解决这个问题。

滑动冲突:

1、NestedScrollView嵌套RecyclerView

坑:NestScrollView嵌套RecyclerView时,事件还是会被NestScrollView消费,RecyclerView的滚动监听无效,而且会加载所有item,其内部的缓存起不到作用。

2、内部拦截:

在继承RecyclerView重写方法:

requestDisallowInterceptTouchEvent方法阻止拦截。

ScrollView 套 ViewGroup 套 RV 。所以是getParent()调用该方法。

    @Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {Log.e("MyListView","dispatchTouchEvent·····"+ev.getAction());switch (ev.getAction()){case MotionEvent.ACTION_DOWN:getParent().requestDisallowInterceptTouchEvent(true);break;case MotionEvent.ACTION_MOVE:boolean a = !canScrollVertically(-1);boolean b = ev.getY()-firstY>0;boolean c = !canScrollVertically(1);boolean d = ev.getY()-firstY<0;if ( (b&&a) || (c&&d) )getParent().requestDisallowInterceptTouchEvent(false);break;}firstY = ev.getY();boolean result =super.dispatchTouchEvent(ev);return result;}

3、外部拦截:

重写ScrollView的onInterceptTouchEvent方法进行判断什么时候该返回true。

RecycleView拖拽跟侧滑功能:ItemTouchHelper类

https://blog.csdn.net/weixin_39706415/article/details/87929441

Android—RecyclerView相关内容相关推荐

  1. android 内核内存管理,Android内核相关内容总结

    要想充分掌握Android这一操作系统的应用,首先需要我们从Android内核的相关内容开始了解.在这里就为大家详细介绍一下相关的知识. Android操作系统是由谷歌推出的一款基于Linux平台开源 ...

  2. Android开发环境——Eclipse ADT相关内容汇总

     Android开发环境将分为SDK相关内容.Eclipse ADT相关内容.模拟器AVD相关内容.调试器DDMS相关内容.日志LogCat相关内容.连接驱动ADB相关内容.内存泄露检测工具MAT相关 ...

  3. Android开发环境——模拟器AVD相关内容汇总

    Android开发环境将分为SDK相关内容.Eclipse ADT相关内容.模拟器AVD相关内容.调试器DDMS相关内容.日志LogCat相关内容.连接驱动ADB相关内容.内存泄露检测工具MAT相关内 ...

  4. android Wifi开发相关内容

    今天,简单讲讲android里如何使用WifiManager. 之前,我看代码时,看到了wifi相关的代码,发现自己对于这个内容的使用还很不熟悉,所以在网上查找资料,最终解决了问题.这里记录一下. 移 ...

  5. linux/android驱动工程师面试相关内容总结

    理论的东西不常用时就会慢慢的被遗忘,但是找工作就是一个如何让别人相信自己的过程,理论知识就是一个非常重要的途径. 一次次机会在错失,每次想找工作时,刷一下简历就去面试了,一次次因为理论被鄙视,也该长长 ...

  6. Android studio根据文本提取出的关键词在sqlite数据库中查找相关内容

    Android studio根据文本提取出的关键词在sqlite数据库中查找相关内容 一.介绍 二.Android studio连接.操作和查看sqlite数据库 三.在数据库中查找相关内容 四.运行 ...

  7. Android RecyclerView最全使用详解

    本文目录 RecyclerView概述 RecyclerView使用-基础篇 第一步:添加RecyclerView 第二步:添加布局文件 第三步:添加逻辑代码 运行效果 RecyclerView使用- ...

  8. Android RecyclerView

    一.RechclerView简介. RecyclerView比listview更先进更灵活,对于很多的视图它就是一个容器,可以有效的重用和滚动. 1.可以通过设置LayoutManager可以实现Li ...

  9. 修改 Android Studio 相关模板,以加快项目创建时构建速度,支持Mac,Windows,Linux...

    2019独角兽企业重金招聘Python工程师标准>>> 注: 本文主要在Mac中操作,Windows,Linux操作类似.默认创建Empty Activity项目 Android S ...

最新文章

  1. 台式机BIOS被加密后密码忘记解决办法
  2. Docker、kubernetes、微服务、SpringBoot/Cloud...好乱!到底要不要学?
  3. oracle password_verify_function,使用PASSWORD_VERIFY_FUNCTION设置用户密码复杂度
  4. php点击查看更多,微信小程序加载更多和点击查看更多功能介绍
  5. python 文件读写(追加、覆盖)
  6. 福州公交车与拖拉机相撞1人死亡
  7. kafka报错:creating broker listeners from xxx unable to parse xxx:9092 to a broker endpoint
  8. .NET进销存系统开发笔记------之Gridview应用
  9. JExcel - 学习总结(1)
  10. csgo准星设置代码_csgo准星代码怎么输入
  11. KinectV2 qt opencv 实现平面测量
  12. 卸载手机自带的系统软件
  13. 创业者需要了解的基本财务知识
  14. Matlab GUI程序封装成exe文件并在不安装Matlab的电脑上运行
  15. 《C语言及程序设计》实践参考——n=a!+b!+c!
  16. python生成的excel无法打开-Python 解决中文写入Excel时抛异常的问题
  17. keepalived配置,解决vip无法ping通,虚拟服务器端口无法访问的问题
  18. 如何解除计算机方向键问题,笔记本键盘上下左右键怎么解锁_笔记本电脑的上下左右键被锁住了如何解决-win7之家...
  19. 几种常用的像素混合方法
  20. PM981/PM981a安装黑苹果-Paragon Hard Disk Manager教程

热门文章

  1. 三圆相交阴影部分面积_小学六年级图形面积的题很多家长都不会,一些初中生也未必会做...
  2. oracle awr 数据删除,Oracle AWR 删除历史快照 说明【转自dave偶像大神】
  3. html转换react native,React native HTML entities
  4. cryptojs vue 使用_VueJs里利用CryptoJs实现加密及解密的方法示例
  5. 佳能g3800故障灯说明书_车子保养后跑了没多久跳出一个扳手样子的灯,是什么意思?...
  6. 本科、硕士、博士,究竟有何区别?
  7. 嵌入式牛人 | 这些单片机编程思想超硬核
  8. 线上课程推荐 | 计算机方向:无人驾驶中的环境感知
  9. box2d 碰撞检测_(译)如何使用box2d来做碰撞检测(且仅用来做碰撞检测)
  10. mysql查询大于0的标记_MySQL如何查询回答数大于0的问题并分页