<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
public class MainActivity extends AppCompatActivity implements SimpleAdapter.OnItemClickListener {
private RecyclerView mRecyclerView;
private List<String> mDatas;
private SimpleAdapter mAmAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initDatas();
initView();
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
final int itemId = item.getItemId();
switch (itemId) {
case R.id.action_add:
mAmAdapter.addData(1);
mRecyclerView.setAdapter(mAmAdapter);
break;
case R.id.action_delete:
mAmAdapter.deleteData(1);
mRecyclerView.setAdapter(mAmAdapter);
break;
case R.id.action_grid_view:
mRecyclerView.setAdapter(new SimpleAdapter(this, mDatas, false));
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 5));
break;
case R.id.action_list_view:
mRecyclerView.setAdapter(new SimpleAdapter(this, mDatas, true));
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
break;
case R.id.action_hor_grid_view:
mRecyclerView.setAdapter(new SimpleAdapter(this, mDatas, false));
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(5, StaggeredGridLayoutManager.HORIZONTAL));
break;
case R.id.action_stagger_view:
startActivity(new Intent(this, StaggeredGridViewActivity.class));
break;
default:
break;
return super.onOptionsItemSelected(item);
private void initView() {
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
mAmAdapter = new SimpleAdapter(this, mDatas, true);
// 设置RecyclerView的布局管理
mRecyclerView.setAdapter(mAmAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false));
mAmAdapter.setOnItemClickListener(this);
private void initDatas() {
mDatas = new ArrayList<>();
for (int i = 'A'; i < 'z'; i++) {
mDatas.add("" + (char) i);
@Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this, "Click:" + position
, Toast.LENGTH_LONG).show();
@Override
public void onItemLongClick(View view, int position) {
mAmAdapter.deleteData(position);
RecycleView 和 ListView 一样需要适配器的,但是 RecycleView 需要设置 布局管理器(setLayoutManager),这是为了方便扩展,这里使用了 LinearLayoutManager.其中 Adapter 的创建比较关键,来看一下 SimpleAdapter 的代码:
public class SimpleAdapter extends RecyclerView.Adapter<MyViewHolder> {
public LayoutInflater mInflater;
private Context mContext;
private List<String> mDatas;
private boolean mIsListView;
public OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
public void setOnItemClickListener(OnItemClickListener listener) {
this.mListener = listener;
public SimpleAdapter(Context context, List<String> datas, boolean isListView) {
this.mContext = context;
this.mDatas = datas;
this.mInflater = LayoutInflater.from(context);
this.mIsListView = isListView;
public void addData(int position) {
if (position >= 1) {
mDatas.add(mDatas.get(position));
notifyItemInserted(position);
public void deleteData(int postion) {
mDatas.remove(postion);
notifyItemRemoved(postion);
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
final View view = mInflater.inflate(mIsListView ? R.layout.item_simple_list_view : R.layout.item_simple_text_view, parent, false);
MyViewHolder viewHolder = new MyViewHolder(view);
return viewHolder;
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
holder.tv.setText(mDatas.get(position));
setUpItemEvent(holder);
public void setUpItemEvent(@NonNull final MyViewHolder holder) {
if (mListener != null) {
final int layoutPosition = holder.getLayoutPosition();
holder.tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mListener.onItemClick(holder.tv, layoutPosition);
holder.tv.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
mListener.onItemLongClick(holder.tv, layoutPosition);
return false;
@Override
public int getItemCount() {
return mDatas.size();
上面用到 item_simple_text_view.xml 布局文件,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:background="@color/colorAccent"
android:layout_margin="3dp"
android:id="@+id/layout_frame"
android:layout_height="wrap_content">
<TextView
android:id="@+id/id_tv"
android:gravity="center"
android:layout_width="72dp"
android:layout_height="72dp"/>
</FrameLayout>
SimpleAdapter 继承 RecyclerView.Adapter ,需要一个ViewHolder 泛型,创建 ViewHolder 需要继承 RecycleView.ViewHolder , ViewHolder 的构造方法需要传递 View 对象, View 对象 需要继承 RecycleView.ViewHolder,ViewHolder 构造方法需要传递 View对象,View对象会和 ViewHolder 进行绑定.
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.id_tv);
可以发现 RecyclerView.Adapter 设计针对性很强,强制程序员通过ViewHolder 和 复用 View 进行优化,不会出现之前 ListView 不采取 优化情况.这种机制避免创建过多View和频繁调用findViewById的方法
写完这些代码后,这个simple就可以运行起来了,从例子也可以看出,RecycleView的用法并不比 ListView 复杂,反而更加灵活好用,它将数据,排列方式,数据展示方式都分割开来,因此自定义的形式也非常多,非常灵活
RecyclerView不同布局的排列方式
上面的效果是水平列表,还可以选择其他排列方式,非常灵活,这就是比单一的listView/GridView强大的地方
ListView
以垂直列表方式展示显示项目
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
GrideView
以垂直列表方式展示显示表格布局
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 5));
横向 ListView
如果想设置一个横向的列表,只要设置 LinearLayoutManager 就行,注意, 要声明 LayoutManager 的类型是 LinearLayoutManager ,而不是父类的 LayoutManager
mRecyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false));
横向 GrideView
以水平列表方式展示显示表格布局
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(5, StaggeredGridLayoutManager.HORIZONTAL))```
一.高度绘制
for (int i = 0; i < mDatas.size(); i++) {
mHeight.add((int) (100 + Math.random() * 300));
二.布局绘制
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
final ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
layoutParams.height = mHeight.get(position);
holder.itemView.setLayoutParams(layoutParams);
holder.tv.setText(mDatas.get(position));
三.设置RecyclerView的布局管理
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(manager);
四.RecyclerView添加点击事件
当使用一段时间的RecycleView,发现为其实现每一项点击事件并没有ListView那么轻松,ListView直接加一个 OnItemClickListerner 即可,实际上我们不要把
RecyclerView 当作 ListView使用,希望大家把他看成一个容器,里面包含不同的item,它们可以设置不同方式的排列组合,非常灵活,点击事件按照自己的意愿进行实现.那么如何为RecycleView添加点击事件呢?
其实我发现,Adapter是添加点击事件一个很好的地方,里面构造布局等View的主要场所,也是布局和数据进行绑定的地方,首先在 Adapter 中创建一个实现点击接口,其中View是点击 item,data是数据,postion是条目位置,因为我们想知道点击的区域部分的数据和位置是什么,以便下一步进行操作:
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
定义完接口,在 Adapter 中添加 要实现的接口和添加设置的方法
public OnItemClickListener mListener;
public void setOnItemClickListener(OnItemClickListener listener) {
this.mListener = listener;
那么这个接口用在什么地方呢?如下代码,为Adapter 实现 onClickListerner 方法:
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
holder.tv.setText(mDatas.get(position));
setUpItemEvent(holder);
public void setUpItemEvent(@NonNull final MyViewHolder holder) {
if (mListener != null) {
final int layoutPosition = holder.getLayoutPosition();
holder.tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mListener.onItemClick(holder.tv, layoutPosition);
holder.tv.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
mListener.onItemLongClick(holder.tv, layoutPosition);
return false;
做完这些事情就可以在 Activity 或者其他地方 为 RecycleView 添加项目点击事件了,如:
private void initView() {
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
mAmAdapter = new SimpleAdapter(this, mDatas, true);
// 设置RecyclerView的布局管理
mRecyclerView.setAdapter(mAmAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false));
mAmAdapter.setOnItemClickListener(this);
@Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this, "Click:" + position
, Toast.LENGTH_LONG).show();
@Override
public void onItemLongClick(View view, int position) {
mAmAdapter.deleteData(position);
五.RecycleView添加删除数据
以前在ListView中,只要 修改数据后用 Adapter 的 notifyDatasetChange 一下就可以更新界面.然而,在RecycleView 中还有高级的用法,可以让添加或者删除条目自带动画,可以在SimpleAdapter 传创建 addItem 和 removeItem 方法.
添加数据:
public void addData(int position) {
if (position >= 1) {
mDatas.add(mDatas.get(position));
notifyItemInserted(position);
删除数据:
public void deleteData(int postion) {
mDatas.remove(postion);
notifyItemRemoved(postion);
注意,这里更新数据集不是 adapter.notifyDataSetChange(),而是 notifyItemInserted(postion)与 notifyItemRemoved(postion),否则没有动画效果
RecyclerView核心类
Adapter
使用RecyleView之前需要继承 自 RecyleView.Adapter 的适配器,作用是将适配器与每一个 item 界面进行绑定
ViewHolder
viewHolder 和 item view 是什么关系?一对一?一对多?还是多对一?
view Holder 解决的是什么问题?
view Holder 的 Listview item view 复用有什么关系?
没有实现 view Holder 的 getView() 会重复执行 findViewById,findViewById 底层实现是一个 dns ,深度优先复杂度,所以viewHolder模式实现了getView方法,他的来历是用来保存View的convertView
不实现 view Holder 还会复用 item view 吗?这个问题我还有待研究.
LayoutManager
LayoutManager 用来确定 每一个 item 如何排列摆放,何时展示和隐藏.回收或重用一个View时,LayoutManager会向适配器请求的数据替换旧的数据,这种机制避免创建过多的View和频繁调用findViewById的方法
ItemDecoration
ItemAnimation
RecyclerView与ListView相比的优势
因为ListView只有纵向列表一种布局,不像RecyleView一样支持 Linear, Grild ,Stagged,Stagged ,Grid 各种可扩展布局,没有支持动画的API,但是RecyleView可以通过ItemAnimation自定义你想要的动画,相关监听接口如:setOnClickListerner(),setOnLongItenListerner(),setSelection()的设计和系统也不一致,并且没有强制实现ViewHolder,RecyleView做到了这一点,降低了耦合,另外ListView性能也不如RecyclerView,所以强烈推荐大家使用RecyclerView
RecyclerView 滑动场景下的回收复用涉及到的结构体两个:
mCachedViews 和 RecyclerViewPool
mCachedViews 优先级高于 RecyclerViewPool,回收时,最新的 ViewHolder 都是往 mCachedViews 里放,如果它满了,那就移出一个扔到 ViewPool 里好空出位置来缓存最新的 ViewHolder。
复用时,也是先到 mCachedViews 里找 ViewHolder,但需要各种匹配条件,概括一下就是只有原来位置的卡位可以复用存在 mCachedViews 里的 ViewHolder,如果 mCachedViews 里没有,那么才去 ViewPool 里找。
在 ViewPool 里的 ViewHolder 都是跟全新的 ViewHolder 一样,只要 type 一样,有找到,就可以拿出来复用,重新绑定下数据即可。
如果不要求动画,可用通过 ((SimpleItemAnimator) rv.getItemAnimator()).setSupportsChangeAnimations(false); 把默认动画关闭来提高性能
TextView 使用 String.toUpperCase 替换 android:textAllCaps="true"
TextView 使用 StaticLayout 或者 DynamicLayout 来自定义view替换它
重新 RecyclerView.onViewRecycled(holder) 回收资源
RecycleView.setItemViewCacheSize(size) 加大 RecyclerView 缓存空间,利用空间换时间策阅来提高流程性
如果多个 RecyclerView 的 adapter 是一样的,比如嵌套的 RecyclerView 存在一样的adapter,可以通过 RecyclerView.setRecycledViewPool(pool); 共有一个 RecycledViewPool
对于 ItemView 设置监听器,不要对每一个 item 都调用 addXxListener,应该共有一个 XxListener 根据 id 来进行不同操作,优化了对象的频繁创建带来的资源消耗。
通过 getExtraLayoutSpace 来增加 RecyclerView 预留的额外空间(显示范围内,应该额外缓存的空间) ,如下所示:
new LinearLayoutManager(this) {
@Override
protected int getExtraLayoutSpace(RecyclerView.State state) {
return size;
recyclerView算是Android中比较常用的控件了,平常的使用也很简单,没什么说的。
另外,recyclerView也经常会有嵌套使用和多条目布局的使用方法,嵌套使用时要注意处理是否有滑动冲突,多条目布局就是定义多个ViewHolder来区分不同的条目。
另外使用itemDecoration可以灵活控制布局之间的间距和装饰等效果。
缓存机制的话确实还没读过源码,找了篇技术文章,可以参考下:https://blog.csdn.net/wzy_1988/article/details/81569156
RecyclerView vs ListView
ListView相比RecyclerView,有一些优点:
1.addHeaderView(), addFooterView()添加头视图和尾视图。
2.通过”android:divider”设置自定义分割线。
3.setOnItemClickListener()和setOnItemLongClickListener()设置点击事件和长按事件。
这些功能在RecyclerView中都没有直接的接口,要自己实现(虽然实现起来很简单),因此如果只是实现简单的显示功能,ListView无疑更简单。
RecyclerView相比ListView,有一些明显的优点:
1.默认已经实现了View的复用,不需要类似if(convertView == null)的实现,而且回收机制更加完善。
2.默认支持局部刷新。
3.容易实现添加item、删除item的动画效果。
4.容易实现拖拽、侧滑删除等功能。
RecyclerView是一个插件式的实现,对各个功能进行解耦,从而扩展性比较好。
找到一篇基本可以全面了解recyclerview的文章,可以参考下
https://www.jianshu.com/p/4f9591291365
RecyclerView vs ListView
ListView相比RecyclerView,有一些优点:
1.addHeaderView(), addFooterView()添加头视图和尾视图。
2.通过”android:divider”设置自定义分割线。
3.setOnItemClickListener()和setOnItemLongClickListener()设置点击事件和长按事件。
这些功能在RecyclerView中都没有直接的接口,要自己实现(虽然实现起来很简单),因此如果只是实现简单的显示功能,ListView无疑更简单。
RecyclerView相比ListView,有一些明显的优点:
1.默认已经实现了View的复用,不需要类似if(convertView == null)的实现,而且回收机制更加完善。
2.默认支持局部刷新。
3.容易实现添加item、删除item的动画效果。
4.容易实现拖拽、侧滑删除等功能。
RecyclerView是一个插件式的实现,对各个功能进行解耦,从而扩展性比较好。
找到一篇基本可以全面了解recyclerview的文章,可以参考下
https://www.jianshu.com/p/4f9591291365
那你是如何解决下划线渲染两次的呢?
使用LinearLayoutManager.setInitialPrefetchItemCount(count)设置嵌套在内部的横向RecyclerView的初次显示Item个数
Item高度固定时(数据变化也不会导致Item高度变化),使用RecyclerView.setHasFixedSize(true)
多个RecyclerView共用一个RecyclerViewPool
DiffUtil局部刷新
RecyclerView缓存
第一层Scrap & 第二层Cache:缓存当前屏幕的ItemView。都是根据position去缓存和获取复用ItemView,复用时不需要再调用onBindViewHolder()重新进行数据绑定了。
第三层ViewCacheExtension:开发者自定义的缓存策略
第四层缓存池:存放已经滑出屏幕的View,需要复用时根据item type去查找是否有可复用的ItemView,如果有可复用的就拿出来再重新进行数据绑定,没有就调用onCreateViewHolder()再新建一个ItemView。
RecyclerView 核心要点
RecycleView 是什么
A flexible view for providing a limited window into a large data set
为有限的屏幕显示大量的数据的灵活的视图
ListView 的局限
只支持纵向列表的滑动
没有支持动画的 API
接口设计和系统设计不一致
setOnItemClickListener()
setOnItemLongClickListener()
setSelection()
没有强制实现 ViewHolder
没有实现ViewHolder 的 getView();
每次都实现findViewById() DFS 浪费时间,消耗性能a/需要实现 ViewHolder 并且 ItemView.setTag(ViewHolder)
性能不如 RecycleView
RecycleView 的优势
默认支持 Linear,Grid,Staggered Grid 三种布局
友好的 ItemAnimator 动画 API
强制实现 ViewHolder
解耦的架构设计
RecycleView
LayoutManager
ItemAnimator
Adapter
两层缓存机制
Active View:指屏幕能看到的 ItemView
Android 刷新屏幕的时候会将屏幕中的 View 清空掉,再加进来,这时回收的使用的就是Active View,这时不需要重新绑定
Scrap View:屏幕中看不到的 ItemView
RecycleView 缓存原理
RecycleView 缓存的是 ViewHolder ,使用了四层缓存机制
Scrap:屏幕内部的 ItemView,通过数据集的 Position 找到的,可以直接复用不需要绑定
Cache:移出屏幕的 ItemView 放入一个CacheView(默认个数为2),就是比屏幕多两个 ItemView, 方便来回翻少量的View,可以直接复用不需要绑定
ViewCacheExtension:用户自定义的缓存机制
**ViewCacheExtension Example **
广告夹杂在 RecycleView 内,并且不会发生变化,广告和内容分开请求
每页一共有四个广告
短期内不会发生变化
Cache 只关心 position,不关心 view type
RecycleViewPool 只关心 view type,每次都要重新绑定
解决方法:在 ViewCacheExtension 保存四个广告的 Card
RecycleViewPool:被废弃的 ItemView ,内部的 data 都是 dirty 的。通过ViewType来重新Bind数据的
注意广告的 impression
ListView 通过 getView() 统计?准确!用户看到item的时候一定会通过 getView() 「即使发生了复用」
RecycleView 通过 onBindView() 统计?错误!发生复用的时候不通过 onBindView() Scrap,Cache 不回发生重新绑定!
RecycleView 通过 onViewAttachedToWindow() 统计!这时每当 ItemView 出现在用户视野里的时候都会回调。
可能不知道的 RecyclerView 性能优化策略
在 onBindViewHolder() 设置点击监听?
在 onBindViewHolder() 里设置点击监听器会导致重复创建点击监听器,会造成内存抖动
在 onCreateViewHolder()/ViewHolder Constructor 里设置点击监听,ItemView - ViewHolder - View.OnClickListener 三者一一对应
也可以只设置一个 ViewOnClickListener ,坏处是处理逻辑都在一起,还会造成数据耦合严重(要取出点击View的对象)
LinearLayoutManager.setInitialPrefetchItemCount()
内部嵌套中的 RecycleView ,用户滑动到横向滑动的item RecycleView 的时候,由于需要创建更复杂的 RecycleView 及多个子 View,可能会导致页面卡顿
由于 RenderThread(分担主线程的渲染压力,放到这里来执行) 的存在,RecycleView 会进行 prefetch (API 21⬆️)
LinearLayoutManager.setInitialPrefetchItemCount(横向列表初始显示时可见的 item 个数)
只有 LinearLayoutManager 有这个 API
只有在嵌套在内部的RecycleView 才会生效
多个 RecyclerView 共用一个 RecycleViewPool
默认是每一个 RecyclerView 用自己的 RecycleViewPool,可以通过 API 设置共享缓存池
RecyclerView.RecycledViewPool recycledViewPool = new RecyclerView.RecycledViewPool();
mRecyclerView.setRecycledViewPool(recycledViewPool);
mRecyclerView1.setRecycledViewPool(recycledViewPool);
mRecyclerView2.setRecycledViewPool(recycledViewPool);
getViewType
DiffUtil
局部更新方法 notifyItemXXX() 不适用于所有情况
notifyDataSetChange() 会导致整个布局重回,重新绑定所有 ViewHolder,而且会可能失去可能的动画效果
DiffUtil 适用于整个页面需要刷新,但是有部分数据可能相同的情况
内部算法使用的动画规划算法
private DiffUtil.Callback mDiffUtilCallBack = new DiffUtil.Callback() {
//旧列表的长度
@Override public int getOldListSize() {return 0;}
//新列表的长度
@Override public int getNewListSize() {return 0;}
//列表项的ID是否变化了
@Override public boolean areItemsTheSame(int i, int i1) {return false;}
//列表项的内容是否变化了
@Override public boolean areContentsTheSame(int i, int i1) {return false;}
//列表项的哪些内容变化了
@Nullable @Override public Object getChangePayload(int oldItemPosition, int newItemPosition) {
return super.getChangePayload(oldItemPosition, newItemPosition);
在数据量很大的时候异步计算diff
使用 Thread/Handler 将 DiffResult 发送到主线程
使用RxJava 将 calculateDiff 操作放到后台线程执行
使用 Google 提供 AsyncListDiff(Executor)/ListAdapter
RecyclerView内部缓存机制是四级缓存:Scrap、Cache、ViewCacheExtension、RecycledViewPool,RecyclerView是通过LayoutManager里面的Recycler来管理缓存;
1、Scrap:屏幕内部的ItemView,通过数据集的position来找到对应的Item,可以直接取过来用;
2、Cache:刚移出屏幕的ItemView,放到Cache里,当Cache里的ItemView重新进入屏幕时,也是通
过position来找到对应的Item,直接可以使用,不需要走bindViewHolder()。Cache和 Scrap 一样,都是可以直接通过position来找到对应的Item,不需要重新绑定;
3、ViewCacheExtension:自定义缓存,如果有自定义,需要在这里面找,没有的话直接跳过;
4、RecycledViewPool:所有被废弃的ItemView的Pool,该pool里面的Item都是dirty的,需要通过
ViewType来找到数据,找到数据的话,需要重新绑定,不走createViewHodler(),走bindViewHolder()。
据我观察,公用一个 RecycledViewPool,不能达到完美的优化效果,只是节省了内存.
RecyclerView.RecycledViewPool recycledViewPool = new RecyclerView.RecycledViewPool();
mRecycledViewPool.setMaxRecycledViews(1, 10);
mRecycledViewPool.setMaxRecycledViews(2, 10);
mRecycledViewPool.setMaxRecycledViews(3, 10);
mRecycledViewPool.setMaxRecycledViews(4, 10);
mRecycledViewPool.setMaxRecycledViews(5, 10);
mRecyclerView1.setRecycledViewPool(recycledViewPool);
mRecyclerView2.setRecycledViewPool(recycledViewPool);
mRecyclerView3.setRecycledViewPool(recycledViewPool);
比如 mRecyclerView1 type=1,保存了 5个.
在 mRecyclerView2 传入 recycledViewPool,并没有 mRecyclerView1 type=1的5个缓存.
所以,当 mRecyclerView2 第一次 type=1 出来的时候,还是会执行 onCreateViewHolder,onBindViewHolder... ... ????