Android—RecyclerView相关内容
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相关内容相关推荐
- android 内核内存管理,Android内核相关内容总结
要想充分掌握Android这一操作系统的应用,首先需要我们从Android内核的相关内容开始了解.在这里就为大家详细介绍一下相关的知识. Android操作系统是由谷歌推出的一款基于Linux平台开源 ...
- Android开发环境——Eclipse ADT相关内容汇总
Android开发环境将分为SDK相关内容.Eclipse ADT相关内容.模拟器AVD相关内容.调试器DDMS相关内容.日志LogCat相关内容.连接驱动ADB相关内容.内存泄露检测工具MAT相关 ...
- Android开发环境——模拟器AVD相关内容汇总
Android开发环境将分为SDK相关内容.Eclipse ADT相关内容.模拟器AVD相关内容.调试器DDMS相关内容.日志LogCat相关内容.连接驱动ADB相关内容.内存泄露检测工具MAT相关内 ...
- android Wifi开发相关内容
今天,简单讲讲android里如何使用WifiManager. 之前,我看代码时,看到了wifi相关的代码,发现自己对于这个内容的使用还很不熟悉,所以在网上查找资料,最终解决了问题.这里记录一下. 移 ...
- linux/android驱动工程师面试相关内容总结
理论的东西不常用时就会慢慢的被遗忘,但是找工作就是一个如何让别人相信自己的过程,理论知识就是一个非常重要的途径. 一次次机会在错失,每次想找工作时,刷一下简历就去面试了,一次次因为理论被鄙视,也该长长 ...
- Android studio根据文本提取出的关键词在sqlite数据库中查找相关内容
Android studio根据文本提取出的关键词在sqlite数据库中查找相关内容 一.介绍 二.Android studio连接.操作和查看sqlite数据库 三.在数据库中查找相关内容 四.运行 ...
- Android RecyclerView最全使用详解
本文目录 RecyclerView概述 RecyclerView使用-基础篇 第一步:添加RecyclerView 第二步:添加布局文件 第三步:添加逻辑代码 运行效果 RecyclerView使用- ...
- Android RecyclerView
一.RechclerView简介. RecyclerView比listview更先进更灵活,对于很多的视图它就是一个容器,可以有效的重用和滚动. 1.可以通过设置LayoutManager可以实现Li ...
- 修改 Android Studio 相关模板,以加快项目创建时构建速度,支持Mac,Windows,Linux...
2019独角兽企业重金招聘Python工程师标准>>> 注: 本文主要在Mac中操作,Windows,Linux操作类似.默认创建Empty Activity项目 Android S ...
最新文章
- 台式机BIOS被加密后密码忘记解决办法
- Docker、kubernetes、微服务、SpringBoot/Cloud...好乱!到底要不要学?
- oracle password_verify_function,使用PASSWORD_VERIFY_FUNCTION设置用户密码复杂度
- php点击查看更多,微信小程序加载更多和点击查看更多功能介绍
- python 文件读写(追加、覆盖)
- 福州公交车与拖拉机相撞1人死亡
- kafka报错:creating broker listeners from xxx unable to parse xxx:9092 to a broker endpoint
- .NET进销存系统开发笔记------之Gridview应用
- JExcel - 学习总结(1)
- csgo准星设置代码_csgo准星代码怎么输入
- KinectV2 qt opencv 实现平面测量
- 卸载手机自带的系统软件
- 创业者需要了解的基本财务知识
- Matlab GUI程序封装成exe文件并在不安装Matlab的电脑上运行
- 《C语言及程序设计》实践参考——n=a!+b!+c!
- python生成的excel无法打开-Python 解决中文写入Excel时抛异常的问题
- keepalived配置,解决vip无法ping通,虚拟服务器端口无法访问的问题
- 如何解除计算机方向键问题,笔记本键盘上下左右键怎么解锁_笔记本电脑的上下左右键被锁住了如何解决-win7之家...
- 几种常用的像素混合方法
- PM981/PM981a安装黑苹果-Paragon Hard Disk Manager教程
热门文章
- 三圆相交阴影部分面积_小学六年级图形面积的题很多家长都不会,一些初中生也未必会做...
- oracle awr 数据删除,Oracle AWR 删除历史快照 说明【转自dave偶像大神】
- html转换react native,React native HTML entities
- cryptojs vue 使用_VueJs里利用CryptoJs实现加密及解密的方法示例
- 佳能g3800故障灯说明书_车子保养后跑了没多久跳出一个扳手样子的灯,是什么意思?...
- 本科、硕士、博士,究竟有何区别?
- 嵌入式牛人 | 这些单片机编程思想超硬核
- 线上课程推荐 | 计算机方向:无人驾驶中的环境感知
- box2d 碰撞检测_(译)如何使用box2d来做碰撞检测(且仅用来做碰撞检测)
- mysql查询大于0的标记_MySQL如何查询回答数大于0的问题并分页