自定义一个可以设置最大高度的RecycleView

这是我参与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的,性能更好,更灵活,何乐而不用呢,你们说呢

猜你喜欢

转载自juejin.im/post/7033754730350247972

相关文章