为何google推出了RecyclerView,它与ListView相比有什么优势呢?RecyclerView是否可以完全替代ListView呢?
在缓存机制原理方面
ListView与RecyclerView缓存机制原理大致相似。都是离屏的ItemView即被回收至缓存,入屏的ItemView则会优先从缓存中获取。当然他们是的实现细节还是有差异的 。
ListView
ListView有两级缓存;第一层:ActiveViews(用于屏幕内item的快速重用),第二层:ScrapViews(不可见item的缓存)
RecyclerView
RecyclerView有四级缓存。
屏幕内缓存: 在屏幕中显示的ViewHolder。缓存到mChangedScrap(缓存数据已经改变的ViewHolder)和mAttachedScrap中。
屏幕外缓存:列表滑动出屏幕时,ViewHolder会被缓存。缓存到mCachedViews中。(默认大小为2。大小由mViewCacheMax
决定。Recyclerview.setItemViewCacheSize(), 可以设置屏幕外缓存的大小)
缓存池:屏幕外缓存的mCachedViews已满时,会将ViewHolder缓存到RecycledViewPool中。
RecyclerView具有的优势:
1,RecyclerView支持局部刷新和定向刷新。
2,RecyclerView支持刷新动画
3,RecyclerView可以自定义分割线,ListView的分割线比较单一。
4,用RecyclerView可以实现表格布局和瀑布流。
ListView的优势:
1,使用起来比RecyclerView简单
2,支持条目的点击事件。RecyclerView不支持。
面试问题:
1,RecyclerView如何复用Item?
1,会通过Recycler.recycleView()方法将ViewHolder进行缓存。 2,获取缓存的时候,会调用Recycler.getViewForPosition()从四级缓存中获取View。 3,当RecycledViewPool中获取到View时,会去调用bindViewHolder()去绑定数据。 4,ViewHolder的Flag处于更新标识时,也会去调用bindViewHolder()去绑定数据。
2,RecyclerView如何定向刷新Item?
本质是:对指定的Item的ViewHolder刷新数据。 1. 通过Adapter的nofity系列方法,最终会交给AdapterHelper进行数据定向刷新。 2. 本质在UpdateOp中存储更新标识和更新范围,并将UpdateOp存储到AdapterHelper内部的UpdateOp列表中。 3. 在RecyclerView的布局阶段,onLayout->disptachLayout->dispatchLayout1中会去更新ViewHolder的Flag为FLAG_UPDATE。 4. 在布局的第二阶段disptachLayout2()->layoutChildren->layoutChunk,中会通过Recylcer去获取缓存的ViewHolder,因为其Flag为更新标识,因此会执行bindViewHolder进行数据刷新。
3,RecyclerView如何实现局部刷新Item?大致原理?
局部刷新某个ViewHolder的某个控件。 1. 需要调用Adapter具有payload参数的方法notifyItemChanged(int position, Object payload) 2. 需要实现RecyclerView.Adapter中具有参数payload的onBindViewHolder() 3. 原理是将ViewHolderFlag设置为FLAG_STATE,并且添加payload 4. 在布局流程中,会去调用具有payload参数的onBinderViewHolder