下面描述RecyclerView是如何对view进行复用的。
一、RecyclerView的缓存
-
一级缓存:mAttachedScrap
mAttachedScrap中的view不需要
重新bindView
。ScrapView主要用于对于屏幕内可见的ChildView的缓存,缓存中的ViewHolder不需要重新Bind,缓存时机是在onLayout的过程中,并且用完即清空,里面的view只是被detach,不会被remove,在onLayout时会使用;
-
二级缓存:mCacheViews
mCacheViews也不需要重新bind,里面的view是被remove过的,缓存滑动时即将离开RecyclerView的ViewHolder;
-
三级缓存:mViewCacheExtension
-
四级缓存:mRecyclerPool
二、view查找过程
在RecyclerView的view不足时,需要addView,view的查找过程如下,一层层降级获取可使用的view:
-
优先从
mAttachedScrap
列表中查找,查找的position必须和列表中某个holder的position
完全一致
,即:要查找的holder和该缓存里面的某个holder达到完全一致的状态;
-
从
mCachedViews
列表中查找,也需要position完全一致匹配。mCachedViews默认最大缓存为2,当大于该值时,将holder缓存移至RecycledViewPool;
-
mAdapter.hasStableIds()为true时,否则转4:从mAttachedScrap、mCachedViews列表中查找viewType相同的holder,在1、2都失败的情况下,说明position完全匹配失败,这时候需要找到viewType相同的holder缓存;
-
从RecycledViewPool里面根据viewType查找缓存的holder。
说明
:RecycledViewPool针对每一种viewType有一个缓冲池,池子大小默认为5,当某一种viewType的holder在RecycledViewPool中的缓存数量大于最大值时,会被丢弃;
-
缓存全部无法命中,则调用Adapter.createViewHolder新建holder。
本文以通俗的语言,记录在阅读RecyclerView源码时的一些心得????。添加view的过程在使用recyclerView的setAdapter方法设置adapter时,会调用RecyclerView的requestLayout()方法,进而执行measure、layout等生命方法;何时添加的子view(adapter里面的一堆):在RecyclerView执行layout时,实际会调用L...
RecyclerView
的功能强大之处就不用说了,但是相比于list
view
来说,它也有些小缺点,比如:没有了间隔线divider,没有
add
Header
View
、
add
Footer
View
等方法,所以用起来不是那么方便。今天主要完成
RecyclerView
的
add
Header
View
和
add
Footer
View
方法。
运行效果如下:第一步:自定义
RecyclerView
,代码如下:public
不多说直接上代码
先是
RecyclerView
的配置
m
RecyclerView
.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
m
RecyclerView
.setHasFixedSize(true);
mAd...
LayoutManager:
1.get
View
ForPosition():是Recycler的方法,在需要获取新的
View
时直接申请,返回的
View
可能是之前回收的垃圾
View
,也可能是new出来的新
View
(
RecyclerView
完成);
取
View
时,
项目
中
有这么一个需求:
要做一个类似相册功能,多张相册滑动,但是每个页面
中
可能有多张图片组成,位置不确定,需要后台确定.
看完需求后,想都不用想直接使用
recyclerview
,item的根布局为Relativelayout,通过LayoutParams和后台给的数据确定位置和大小,最后
add
View
添加
到
view
Group
中
:效果和预想的一样
但是最后滑动多张后,发现点击空白处,实际上对应其他...
利用Window.
add
View
(),滑动时updatePosition
利用
RecyclerView
.
add
View
(),滑动时改变漂浮控件float
View
的layoutParams.margin
第一种,利用Window更新位置稍微复杂点,放弃。
第二种,Recycl...
1.1、从上图
中
看出:Recycle
View
的缓存从上到下分为四层:scrap、cache、
View
CacheExtension、Recycle
View
Pool
1.2、Recycle
View
缓存的对象是
View
Holder,而Recycle
View
复用
的对象也是
View
Holder
1.3、Recycler负责管理和缓存所有的
View
Holder。
2、四级缓存介绍:
2.1、scrap:
从图
中
可以看出,scrap是用来缓存正在显示的
View
H.
Android
RecyclerView
Android
RecyclerView
支持
add
Header
View
,
add
Footer
View
和loadMore。
##代码设置
添加
head
View
MfRecycyler
View
m
RecyclerView
; m
RecyclerView
.
add
Header
View
(header
View
);
添加
footer
View
m
RecyclerView
.
add
Footer
View
(footer
View
);
设置empty
View
m
RecyclerView
.setEmpty
View
(empty
View
);
RecyclerView
滑动到底部m
RecyclerView
.
add
OnScrollListener(new OnRcvScrollListener(OnRcvScrollListener.LAYOUT_MANAGERTYPE.LINEAR,
第一篇,给recycle
view
添加
header,footer,empty
view
。
最近有开发一个列表,这个列表需要
添加
header和footer的功能。记录一下,避免每次开发都去查找相关代码。
代码示例:
(1)adapter:
public class MessageCenterAdapter extends Recycle...
RecyclerView
作为List
View
的替代者有着较好的性能提升,但是有些List
VIew
的常用功能却没有提供比如
add
Header
View
,
add
Footer
View
;
作为替代方案,可以通过自定义的Adapter来实现
add
Header
View
,
add
Footer
View
功能,代码如下:
public class HeaderAdapter extends
RecyclerView
.
文章目录前言使用方式(kotlin)自定义Recycle
View
(kotlin)腾讯bugly
中
示例代码疏漏地方引用
有时候我们在使用Recycle
View
的时候需要在没有数据的时候设置empty
View
。这里通过对Recycle
View
进行拓展来设置empty
View
.本质上是通过有数据时候隐藏Recycle
View
显示empty
View
,无数据时候通过隐藏empty
View
显示Recycle
View
来处理的。本例参考腾讯Bugly的代码,但是示例代码有疏漏,所以这里给出原因及解决方式。
使用方式(
<h3>回答1:</h3><br/>在使用 Android 的 NestedScroll
View
嵌套
RecyclerView
的过程
中
,出现了数据无法
复用
缓存的问题,这是因为
RecyclerView
的
复用
机制并不适用于 NestedScroll
View
中
的嵌套情况。
NestedScroll
View
中
包含的
RecyclerView
实际上是作为一个子
View
的形式出现的,而每一个子
View
的布局和数据都是不同的,所以
RecyclerView
无法反复利用之前已经使用过的缓存。这会导致在滑动过程
中
不断创建新的
View
Holder,从而降低应用程序的性能。
为了解决这个问题,可以将
RecyclerView
操作放到调用 NestedScroll
View
的 onScrollChanged() 方法里面,以确保它的缓存机制被正确使用。另外,为
RecyclerView
设置setHasFixedSize(true)属性可以使性能有一些提升。
最好的解决方案是使用单个
RecyclerView
以及多个 Adapter 对其进行管理。这种方法可以让您更好地控制与管理
RecyclerView
的数据,在保证 NestedScroll
View
能够适当地管理视图树的同时,确保
RecyclerView
没有内存和性能问题。
<h3>回答2:</h3><br/>Android
中
,
RecyclerView
是一个非常高效的列表控件,它可以使用
View
Holder机制对视图进行缓存,减少频繁更新视图的开销,但是在使用NestedScroll
View
嵌套
RecyclerView
时,却会出现数据无法
复用
缓存的问题。
这是因为NestedScroll
View
默认会将
RecyclerView
的所有子视图都展开,导致
RecyclerView
中
所有的子视图都处于可见状态,无法被缓存。因此,当列表滑动时,
RecyclerView
会重新实例化缓存的
View
Holder,以展示新的子视图。这个过程会消耗大量的内存和CPU,导致
RecyclerView
变得非常缓慢,甚至会导致OOM崩溃等问题。
为了解决这个问题,我们需要使用一些技巧来保证
RecyclerView
的子视图只有在需要的时候才被展开。一种解决方案是通过设置NestedScroll
View
的fill
View
port属性为false,使NestedScroll
View
不将
RecyclerView
的所有子视图都展开。这样做可以让
RecyclerView
正确地使用
View
Holder机制,但是在滑动过程
中
,子视图的高度会频繁变化,导致列表的抖动,用户体验也会受到一定的影响。
另一种解决方案是使用
RecyclerView
的setRecycled
View
Pool()方法,为
RecyclerView
缓存一个视图池,这个视图池可以在
RecyclerView
的所有嵌套层级间共享,让所有子视图都可以被重复使用。这个方案的优点是可以减少在滑动过程
中
子视图高度变化带来的问题,但是需要在代码
中
进行额外的编写。
总之,NestedScroll
View
嵌套
RecyclerView
在使用时要注意子视图的缓存问题,需要通过调整布局属性或使用
RecyclerView
的视图池等技巧来解决。
<h3>回答3:</h3><br/>Android的嵌套滑动规范是在Android 5.0(API level 21)
中
引入的,用于使父
View
和子
View
之间的滑动效果更加协调。而NestedScroll
View
和
RecyclerView
都是Android
中
常用的滑动控件,但是在嵌套使用的过程
中
,
RecyclerView
的数据无法
复用
缓存,这是为什么呢?
首先,我们需要了解
RecyclerView
的缓存机制。
RecyclerView
使用三种缓存机制:首先是
View
Holder缓存,它可以在滑动时快速重新绑定已经存在的
View
Holder对象;其次是
View
缓存,它缓存了滑出屏幕的
View
,可以加速滑动时的UI响应;最后是Bitmap缓存,它用于缓存在
RecyclerView
中
的图像。
然而,在嵌套使用NestedScroll
View
和
RecyclerView
时,
RecyclerView
的缓存机制无法发挥作用。这是因为NestedScroll
View
将滑动事件先处理,然后再将滑动事件交给
RecyclerView
处理,这会重新调用
RecyclerView
的Adapter
中
的get
View
()方法,导致
RecyclerView
中
的缓存被清空。因此,
RecyclerView
的数据无法
复用
缓存,会造成性能上的损失。
为了解决这个问题,可以采取以下措施:
1.不要嵌套滑动控件:尽量避免使用NestedScroll
View
和
RecyclerView
等嵌套滑动控件。
2.使用LayoutManager:使用LayoutManager可以缓存
RecyclerView
的
View
Holder对象,加速滑动过程
中
的UI响应。
3.自定义LayoutManager:自定义LayoutManager可以对滑动速度、滑动方向等进行优化,提高
RecyclerView
的性能。
4.使用分组显示:对
RecyclerView
的数据进行分组,将分组内的数据合并成一张图片,然后将图片缓存起来,这样可以减少
RecyclerView
的刷新次数。
总的来说,NestedScroll
View
和
RecyclerView
的嵌套使用会导致
RecyclerView
的缓存无法
复用
,降低
RecyclerView
的性能,因此需要采取一些措施来解决这个问题。使用LayoutManager、自定义LayoutManager、分组显示等方法可以优化
RecyclerView
的性能,提高用户体验。