这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战
前言
RecycleView 是我们继Listview 用的最多的列表展示的控件了,它们有什么区别了呢
RecycleView 和 ListView
1、缓存机制
RecyclerView比ListView多两级缓存,支持多个离ItemView缓存,支持开发者自定义缓存处理逻辑,支持所有RecyclerView共用同一个RecyclerViewPool(缓存池)。
ListView和RecyclerView缓存机制基本一致:
mActiveViews和mAttachedScrap功能相似,意义在于快速重用屏幕上可见的列表项ItemView,而不需要重新createView和bindView;
mScrapView和mCachedViews + mReyclerViewPool功能相似,意义在于缓存离开屏幕的ItemView,目的是让即将进入屏幕的ItemView重用.
RecyclerView的优势在于a.mCacheViews的使用,可以做到屏幕外的列表项ItemView进入屏幕内时也无须bindView快速重用;b.mRecyclerPool可以供多个RecyclerView共同使用,在特定场景下,如viewpaper+多个列表页下有优势.客观来说,RecyclerView在特定场景下对ListView的缓存机制做了补强和完善。
缓存不同: RecyclerView缓存RecyclerView.ViewHolder,抽象可理解为: View + ViewHolder(避免每次createView时调用findViewById) + flag(标识状态);
ListView缓存View。
RecyclerView中mCacheViews(屏幕外)获取缓存时,是通过匹配pos获取目标位置的缓存,这样做的好处是,当数据源数据不变的情况下,无须重新bindView,而同样是离屏缓存,ListView从mScrapViews根据pos获取相应的缓存,但是并没有直接使用,而是重新getView(即必定会重新bindView)
ListView中通过pos获取的是view,即pos–>view;
RecyclerView中通过pos获取的是viewholder,即pos –> (view,viewHolder,flag);
2、RecyclerView 优点
RecyclerView 相比 ListView 在基础使用上的区别主要有如下几点:
ViewHolder 的编写规范化了 RecyclerView 复用 Item 的工作 Google 全帮你搞定,不再需要像 ListView 那样自己调用 setTag RecyclerView 需要多出一步 LayoutManager 的设置工作
3、ListView 使用场景
如果页面不是复杂,也不是需要太多功能,只需要简单的列表功能,那就可以继续使用ListView, 毕竟实现起来比RecyclerView简单些。
自定义可以设置最大高度的RecycleView
项目中有这样的需求,要支持列表有一个最大高度,但是 reycycleview 没有这个属性,那么怎么办呢,没有,我们就创造,哈哈。。。。
class PHMaxHeightRecyclerView : RecyclerView {
//最大高度
private var mMaxHeight = 0
/***
* 设置最大高度
*/
fun setMaxHeight(maxHeight: Int) {
this.mMaxHeight = maxHeight
requestLayout()
}
constructor(context: Context) : super(context) {}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
init(context, attrs)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init(context, attrs)
}
private fun init(context: Context, attrs: AttributeSet?) {
val arr = context.obtainStyledAttributes(attrs, R.styleable.PHMaxRecyclerView)
mMaxHeight = arr.getLayoutDimension(R.styleable.PHMaxRecyclerView_maxHeight, mMaxHeight)
arr.recycle()
}
override fun onMeasure(widthSpec: Int, heightSpec: Int) {
super.onMeasure(widthSpec, heightSpec)
val height = measuredHeight
if (mMaxHeight != 0 && height > mMaxHeight) {
setMeasuredDimension(widthSpec, mMaxHeight)
} else {
setMeasuredDimension(widthSpec, height)
}
}
}
复制代码
使用:
<com.utils.PHMaxHeightRecyclerView
android:id="@+id/max_recycleview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:maxHeight="420mm"
>
</com.utils.PHMaxHeightRecyclerView>
复制代码
是不是很简单
总结
还是推荐大家使用RecycleView,毕竟它出来就是为了 替代ListView 和 GridView的,性能更好,更灵活,何乐而不用呢,你们说呢