Android:RecyclerView封装,打造列表极简加载

前言

kotlin 复制代码
mBinding.recycler.linear().divider()
            .set<OrdinaryListBean> {
                addLayout(R.layout.layout_ordinary_item)
            }.setList(getList())

如果我要说,除了数据和布局之外,以上的几行代码,就实现了一个列表加载,有老铁会相信吗?

可以很负责人的告诉大家,经过Kotlin的DSL语言和扩展函数的使用,实现一个列表加载就是如此的简单,有的老铁可能会很懵,怎么没有看到适配器啊,也没有看到设置布局管理器啊,这就是此次封装的隐秘之处,弱化adapter的存在,当然了只是使用上弱化,其内部依然用到了adapter。

经过代码上不断的完善,功能上不断的拓展,目前的封装,已经满足绝大部分的常见需求,决定开源出来,希望可以给RecyclerView的使用上,带来一丝变化,当然了,此项目也会不定期更新,也欢迎大家在使用上提出自己的见解和问题,也希望点个小星星。

目前已开发功能:

本篇文章的概述如下

1、封装库快速使用

2、具体功能一一概述

3、开源地址

4、使用总结

5、后续规划

一、封装库快速使用

目前封装的库,已经上传到远程Maven,大家可以按照如下的步骤进行使用:

1、在你的根项目下的build.gradle文件下,引入maven。

groovy 复制代码
allprojects {
    repositories {
        maven { url "https://gitee.com/AbnerAndroid/almighty/raw/master" }
    }
}

2、在你需要使用的Module中build.gradle文件下,引入依赖。

groovy 复制代码
dependencies {
    implementation 'com.vip:relist:1.0.5'//一个包含了列表加载和下拉刷新、上拉加载的库,它包含了下面的两个库,使用它,下面的两个就不要引用了。
    implementation 'com.vip:list:1.0.4'//列表加载库,如果使用了relist,这个不要再引用
    implementation 'com.vip:refresh:1.0.0'//下拉刷新、上拉加载库,如果使用了relist,这个不要再引用
}

需要注意的是,目前拆分了三个依赖 ,大家一定看清楚后,进行选择使用。refresh依赖只是对SmartRefreshLayout包了一层,没有做过多的扩展,如果大家项目中已经有了刷新库,其实只用list这个依赖即可。list库是纯RecyclerView封装库,没有用到任何的第三方,大家可以放心使用。

依赖 概述 版本号 集成
relist 一个包含了列表加载和下拉刷新、上拉加载的库 1.0.5 implementation 'com.vip:relist:1.0.5'
list 只包含列表加载(添加头尾、缺省页、侧滑删除、吸顶效果、分割线、DataBinding等) 1.0.4 implementation 'com.vip:list:1.0.4'
refresh 只包含下拉刷新、上拉加载 1.0.0 implementation 'com.vip:refresh:1.0.0'

二、具体功能使用

关于功能上的使用,大家可以直接看源码,或者访问github地址后看使用说明也可以,当然了,在这里我也罗列一下。

1、普通的列表加载

普通的列表加载,就是RecyclerView原始的用法,创建适配器Adapter,给RecyclerView设置布局管理器,给RecyclerView设置适配器,虽然说,Adapter已经抽取封装了,但考虑到还有一部分小伙伴具有怀旧意识,也很喜欢使用这种方式加载列表,于是呢,这种方式就保留了。

具体使用,举例如下:

创建适配器

即便是普通列表加载,这里也是建议继承父类BaseAdapter,因为直接继承RecyclerView.Adapter的方式, 还得要重写一大堆方法,实在是冗余。

BaseAdapter对RecyclerView.Adapter做了一层封装,只需要传递要加载的layout和数据对象泛型即可,这两个就不贴源码了,一个是xml布局,一个自己定义的对象,没啥好说的。

数据绑定和逻辑处理,实现dataOperation方法即可,当然,这个也是强制要实现的方法。

kotlin 复制代码
class OrdinaryListAdapter : BaseAdapter<OrdinaryListBean>(R.layout.layout_ordinary_item) {

    override fun dataOperation(holder: BaseViewHolder, t: OrdinaryListBean?, position: Int) {

        t?.title?.let {
            holder.setText(R.id.tv_title, it)
        }

        t?.desc?.let {
            holder.setText(R.id.tv_desc, it)
        }

        val ivPic = holder.findView<ImageView>(R.id.iv_pic)

        t?.icon?.let {
            ivPic.setImageResource(it)
        }


    }
}

设置布局管理器和适配器

这些代码就比较熟悉了吧,都是RecyclerView的原始用法,点击事件调用adapter中的setOnItemClickListener方法即可。

因为使用了ViewDataBinding,这里的mBinding.recycler指的是RecyclerView控件。

kotlin 复制代码
       val manger = LinearLayoutManager(requireContext())
        manger.orientation = LinearLayoutManager.VERTICAL
        //设置布局管理器
        mBinding.recycler.layoutManager = manger

        val adapter = OrdinaryListAdapter()
        //设置适配器
        mBinding.recycler.adapter = adapter

        //设置分割线
        mBinding.recycler.addItemDecoration(
            ItemDivider(
                Color.parseColor("#cccccc"),
                RecyclerView.VERTICAL, 0
            )
        )

        //设置数据
        adapter.setList(getList())

        adapter.setOnItemClickListener {
            //条目点击事件
            Toast.makeText(requireContext(), "当前点击条目为:$it", Toast.LENGTH_SHORT).show()
        }

简化设置布局管理器和适配器

看到上面的代码,还是觉得有些冗余,普通列表加载,也是建议大家尽量使用简洁用法。

kotlin 复制代码
 val adapter = OrdinaryListAdapter()

  mBinding.recycler.linear()//设置布局管理器
            .divider()//设置分割线
            .adapter=adapter//设置适配器

       //设置数据
        adapter.setList(getList())

        adapter.setOnItemClickListener {
            //条目点击事件
            Toast.makeText(requireContext(), "当前点击条目为:$it", Toast.LENGTH_SHORT).show()
        }
 

布局管理器调用如下:

kotlin 复制代码
垂直列表:linear()
横向列表:linear(RecyclerView.HORIZONTAL)
网格列表:grid(2),一列展示几个,传递数值即可
瀑布流列表:staggered(2),一列展示几个,传递数值即可

至于其他的列表展示,如,网格和瀑布流形式,只需要更改布局管理器即可。

2、封装之后的列表加载

封装之后的列表加载,是推荐使用的,相对于普通的列表加载,完全弱化了适配器的存在,只需要考虑数据处理即可,非常的简单。

kotlin 复制代码
mBinding.recycler.linear()
            .divider()
            .set<OrdinaryListBean> {
                addLayout(R.layout.layout_ordinary_item)
                bindData {
                    //获取DataBinding
                    val binding = getDataBinding<LayoutOrdinaryItemBinding>()
                    //获取Model
                    val model = getModel(adapterPosition)
                    binding?.apply {
                        tvTitle.text = model.title
                        tvDesc.text = model.desc
                        ivPic.setImageResource(model.icon!!)
                    }
                    setOnItemClickListener {
                        //条目点击事件
                        Toast.makeText(requireContext(), "当前点击条目为:$it", Toast.LENGTH_SHORT)
                            .show()
                    }
                }

            }.setList(getList())

相关方法说明:

属性或方法 概述
mBinding.recycler 因为使用了ViewDataBinding,这里的mBinding.recycler指的是RecyclerView控件。
linear 布局管理器,可调用方法如下:垂直列表:linear()横向列表:linear(RecyclerView.HORIZONTAL)网格列表:grid(2),一列展示几个,传递数值即可瀑布流列表:staggered(2),一列展示几个,传递数值即可
divider 分割线
set 扩展函数,泛型为加载的对象
addLayout 添加列表Item展示的布局
bindData 绑定数据和处理逻辑
getDataBinding 获取ViewDataBinding
getModel 获取数据对象
setOnItemClickListener 条目点击事件
setList 设置列表数据

有的老铁可能会问了,封装之后简单是简单了,但是如果遇到复杂列表,都写到一个类里,代码量实在是太多了,哎!这确实是 个问题,但是呢,又不是问题,如果bindData里的逻辑比较多,你完成可以抽取到其他地方,比如ViewModel里,在ViewModel定义 方法后,调用即可,又或者呢,使用后边的DataBinding。

3、多条目列表加载

效果图可以忽略,重在功能哈~,多条目加载也封装了,有适配器和无适配方式,在实际的业务开发中,大家可以选择性进行使用。

有适配器模式

也就是和传统的多条目保持一致,都在适配器里进行数据的渲染和逻辑处理。

还是那句话,多条目的适配器也抽取了基类,既然都有基类了,为了代码上的简洁,建议还是继承基类比较好。

如何添加多条目?

直接在构造方法里,调用addLayout即可,有几个多条目就添加几个,是不是非常的方便,泛型为数据对象,参数为多条目xml布局。

如何数据渲染和逻辑处理?

实现bindOperation方法即可,通过holder.itemViewType来却分多条目的类型,当然了这个必须和数据对象里的类型保持一致。

区分多条目类型

数据对象实现BaseMultipleItem,重写itemViewType属性,itemViewType就是用来区分多条目类型的,可以随意设置,或者是接口的某个参数,或者是对应的layout。

kotlin 复制代码
class OrdinaryMultipleItemAdapter : BaseMultipleItemAdapter {

    constructor() {
        //添加多条目类型以及绑定的数据对象
        addLayout<MultipleItem01Bean>(R.layout.layout_ordinary_multiple_01)
        addLayout<MultipleItem02Bean>(R.layout.layout_ordinary_multiple_02)
        addLayout<MultipleItem03Bean>(R.layout.layout_ordinary_multiple_03)
    }

    override fun bindOperation(holder: BaseViewHolder, t: BaseMultipleItem?, position: Int) {

        when (holder.itemViewType) {
            1 -> {
                val bean = t as MultipleItem01Bean
                holder.setText(R.id.tv_title, bean.title!!)
                holder.setText(R.id.tv_desc, bean.desc!!)
                val ivPic = holder.findView<ImageView>(R.id.iv_pic)
                ivPic.setImageDrawable(bean.icon)
            }
            2 -> {
                val bean = t as MultipleItem02Bean
                val ivPic01 = holder.findView<ImageView>(R.id.iv_01)
                val ivPic02 = holder.findView<ImageView>(R.id.iv_02)
                val ivPic03 = holder.findView<ImageView>(R.id.iv_03)

                ivPic01.setImageDrawable(bean.icon01)
                ivPic02.setImageDrawable(bean.icon02)
                ivPic03.setImageDrawable(bean.icon03)
            }
            3 -> {
                val bean = t as MultipleItem03Bean
                holder.setText(R.id.tv_content, bean.content!!)
            }
        }
    }

}

设置布局管理器和适配器

kotlin 复制代码
val adapter = OrdinaryMultipleItemAdapter()
        mBinding.recycler.linear()
            .divider().adapter = adapter
        adapter.setList(getMoreList())

无适配器模式

无适配器模式,更加的简单,只需要调用setMore方法即可,有多少条目就调用addLayout几次,在bindData里进行数据渲染和逻辑处理,当然了,也可以使用DataBinding形式,需要追加BR。

kotlin 复制代码
mBinding.recycler.linear()
            .divider()
            .setMore {
                addLayout<MultipleItem01Bean>(R.layout.layout_multiple_01, BR.multiple1)
                addLayout<MultipleItem02Bean>(R.layout.layout_multiple_02, BR.multiple2)
                addLayout<MultipleItem03Bean>(R.layout.layout_multiple_03, BR.multiple3)
                bindData {

                }
            }.setList(getMoreList())

4、DataBinding形式列表加载

DataBinding的出现,使得数据绑定更加的简单化,大大减少了代码的书写,大家可以采用提供的两种方式进行使用,一种是针对Item的绑定,一种是对RecyclerView自身的绑定。

Item绑定

第一步,addLayout,增加和xml绑定的BR

kotlin 复制代码
 mBinding.recycler.linear().divider()
            .set<OrdinaryListBean> {
                addLayout(R.layout.layout_ordinary_bind_item, BR.ordinary)
                setOnItemViewClickListener { view, position ->
                    //条目点击事件
                    Toast.makeText(requireContext(), "当前点击条目为:$position", Toast.LENGTH_SHORT).show()
                }
            }.setList(getList())

第二步,xml数据绑定

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="ordinary"
            type="com.abner.list.ordinary.OrdinaryListBean" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/vip_dp_80"
        android:paddingLeft="@dimen/vip_dp_20"
        android:paddingRight="@dimen/vip_dp_20">

        <ImageView
            android:id="@+id/iv_pic"
            android:layout_width="@dimen/vip_dp_60"
            android:layout_height="@dimen/vip_dp_60"
            android:src="@mipmap/vip_list_logo"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/vip_dp_10"
            android:orientation="vertical"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toRightOf="@id/iv_pic"
            app:layout_constraintTop_toTopOf="parent">

            <TextView
                android:id="@+id/tv_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{ordinary.title}"
                android:textColor="#222222"
                android:textSize="@dimen/vip_sp_16" />

            <TextView
                android:id="@+id/tv_desc"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/vip_dp_10"
                android:text="@{ordinary.desc}"
                android:textColor="#666666"
                android:textSize="@dimen/vip_sp_14" />

        </LinearLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

RecyclerView绑定

第一步,xml中RecyclerView数据绑定

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="model"
            type="com.abner.list.bind.RecyclerViewBindViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler"
            listData="@{model.list}"
            listLayout="@{model.layoutId}"
            listManager="@{0}"
            listVariableName="@{model.listVariableName}"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

第二步、对应model中提供数据

kotlin 复制代码
class RecyclerViewBindViewModel : BaseViewModel() {

    val layoutId = R.layout.layout_ordinary_bind_item//item列表

    /**
     * AUTHOR:AbnerMing
     * INTRODUCE:获取视图绑定的name
     */
    fun getListVariableName(): Int {
        return BR.ordinary
    }

    /**
     * AUTHOR:AbnerMing
     * INTRODUCE:模拟数据
     */
    fun getList(): MutableList<OrdinaryListBean> {

        return mutableListOf<OrdinaryListBean>().apply {
            for (a in 0..20) {
                val bean = OrdinaryListBean()
                bean.title = "我是标题$a"
                bean.desc = "我是描述信息$a"
                bean.icon = R.mipmap.vip_list_logo
                add(bean)
            }
        }
    }
}

属性一览

属性 类型 概述
listManager Int 布局管理器:默认为纵向的普通列表。0:普通列表1:网格2:瀑布流
listOrientation Int 设置列表方向,默认纵向。横向:RecyclerView.HORIZONTAL
listSpanCount Int 展示几列,适用于网格和瀑布流
isDivider Boolean 是否展示分割线
dividerDrawable Int 分割线样式
listLayout Int Item布局
listData MutableList<T> 数据
listVariableName Int 绑定的BR
listAdapter OnAdapterListener<T> 返回适配器,可以通过这里实现,适配器中的逻辑处理
isMultiple Boolean 是否是多条目
multipleAdapter OnAdapterMultipleListener 返回多条目适配器
multipleData MutableList<BaseMultipleItem> 多条目数据
multipleLayout MutableList<Int> 多条目布局
multipleLayoutBindData MutableList<Class<*>> layout绑定的数据对象
multipleVariableName MutableList<Int> xml绑定的对应的VariableName

两种绑定方式,各有优点,大家可以根据实际的业务进行选择使用。

5、设置分割线

调用divider方法即可。

kotlin 复制代码
 mBinding.recycler.linear()
            .divider()
            .set<OrdinaryListBean> {
                addLayout(R.layout.layout_ordinary_bind_item, BR.ordinary)
            }.setList(getList())

divider可选参数如下:

参数 类型 概述
color Int 分割线颜色,默认是#cccccc
orientation Int 分割线方向,默认和纵向保持一致,RecyclerView.VERTICAL
lineWidth Int 分割线的高度
margin Int 分割线距离左右或者距离上下的边距
hideLast Boolean 是否隐藏最后一条分割线
itemType Int 默认为0,不为0时,则绘制横向线条,适用于网格列表分割线

6、头和尾追加和删除

头和尾的添加支持layout和View两种添加方式,代码如下所示:

kotlin 复制代码
mAdapter?.addHead(R.layout.layout_head)//初始 添加头  不用刷新
mAdapter?.addFoot(R.layout.layout_foot)//初始 添加尾  不用刷新

后续如果动态添加头尾,需要更新适配器。

kotlin 复制代码
 mAdapter?.addHead(view, true)//追加头,需要刷新
 mAdapter?.addFoot(view, true)//追加尾,需要刷新

动态删除头尾操作,支持按照索引进行删除。

kotlin 复制代码
mAdapter?.removeHead()
mAdapter?.removeFooter()

7、数据追加和删除

初始添加数据

kotlin 复制代码
mAdapter?.setList(getList())

追加数据,支持对象和集合两种方式

kotlin 复制代码
 mAdapter?.addData()

删除数据

kotlin 复制代码
mAdapter?.removeData(0)

8、设置缺省页面

缺省页面没什么好说的,数据为空或者数据加载错误的时候,设置一张占位View。

空页面,调用addEmptyView即可,支持layout和View两种模式,错误页面,调用addErrorView,和空页面使用方式一致。

kotlin 复制代码
 mAdapter = mBinding.recycler.linear()
            .divider()
            .set {
                addEmptyView(R.layout.layout_empty)//初始化 空页面
                addErrorView(R.layout.layout_error)//初始化  错误页面
                addLayout(R.layout.layout_item, BR.str)
            }

        //初始添加数据
        mAdapter?.setList(getList())
功能 实现
显示空 mAdapter?.showEmptyView()
隐藏空 mAdapter?.hintEmptyView()
显示错误 mAdapter?.showErrorView()
隐藏错误 mAdapter?.hintErrorView()

9、拖拽排序功能

调用drag方法即可实现拖拽排序功能。

kotlin 复制代码
 mBinding.recycler.linear()
            .drag()//支持拖拽
            .set<DragBean> {
                addLayout(R.layout.layout_drag_item, BR.drag)
            }.setList(getList())

注意事项

传递的数据对象必须实现BaseNoDragBean,需要重写isDrag属性,false为禁止拖拽,true为允许拖拽。

kotlin 复制代码
class DragBean : BaseNoDragBean {
    override var isDrag = false

    var content = ""

}

10、侧滑删除条目

调用slideDelete方法即可,支持左右侧滑删除,传递不同的值即可。

kotlin 复制代码
 mBinding.recycler
            .linear()
            .slideDelete()//支持侧滑删除 默认是左滑删除 0是右边  1是左右两边
            .set<String> {
                addLayout(R.layout.layout_main_item, BR.str)
            }.setList(getList())

11、侧滑显示按钮

由原来的set方法改为setSlide方法即可。

kotlin 复制代码
 mBinding.recycler
            .linear()
            .divider()
            .setSlide<String> {//如果要显示按钮 使用 setSlide
                addLayout(R.layout.layout_item)
                bindData {
                    val model = getModel(adapterPosition)
                    setText(R.id.tv_content, model)
                }
            }.setList(getList())

有的老铁可能会问,我想展示多个按钮,或者展示自定义的View,如何实现呢?在setSlide调用addSlideLayout,传入自己的xml布局即可。

12、条目吸顶功能

实现吸顶就调用stick方法即可。

kotlin 复制代码
 mBinding.recycler.linear()
            .stick()
            .set<StickHeaderBean> {
                addLayout(R.layout.layout_stick_item, BR.stick)
            }.setList(getList())

需要注意,数据对象需要实现StickHeaderBean,重写分组标识。

kotlin 复制代码
class StickHeaderBean : BaseStickHeaderBean {

    override var stickGroup: String = ""//分组标识

    var name = ""//普通内容
}

13、单选、多选、全选、反选

当然了这都是业务层的逻辑,按理来说,没必要在封装,但是考虑到代码的简洁性,单选和多选的判断逻辑就封装了一下,大家如有用到此功能,可按照如下的方式进行操作即可。

单选

主要的就两部分:

1、开启单选刷新

mNotifySingleChoice = true

2、判断单选

adapterPosition == mCheckPosition,可以利用mCheckPosition来判断,进而更新UI。

kotlin 复制代码
mBinding.recycler.linear().divider().set<SingleBean> {
            mNotifySingleChoice = true//开启单选刷新
            addLayout(R.layout.layout_single_choice_list_item, BR.single)
            bindData {
                val binding = this.getDataBinding<LayoutSingleChoiceListItemBinding>()
                //判断单选,直接判断  adapterPosition == mCheckPosition 即可
                binding?.checkbox?.isChecked = adapterPosition == mCheckPosition
                setOnItemViewClickListener { view, position ->
                    //条目点击
                    val singleBean = getList()[position]//单选 选择的对象
                    mViewModel.name.set(singleBean.name)
                }
            }
        }.setList(getList())

多选

和单选一样,也是两部分

1、设置多选更新

mNotifyMultipleChoice = true

2、多选回调监听

setOnMultipleChoiceListener{}

kotlin 复制代码
mBinding.recycler.linear().divider().set<MultipleBean> {
            mNotifyMultipleChoice = true//多选更新
            addLayout(R.layout.layout_multiple_choice_list_item, BR.multiple)
            bindData {
                //多选回调监听
                setOnMultipleChoiceListener {
                    var allPrice = 0.0f
                    it.forEach {
                        allPrice += it.price
                    }
                    mViewModel.commodityNumber.set("选择商品数量为:" + it.size)
                    mViewModel.allPrice.set("总价格为:$allPrice")
                }
            }
        }.setList(getList())

14、上拉刷新和下拉加载

刷新和加载使用的是SmartRefreshLayout这个开源框架,毕竟已经有很优秀的框架了,没必要再重新封装一个,具体的用法,大家可以按照SmartRefreshLayout的文档去操作使用就行。

支持全局设置下拉和上拉展示View,只需要在Application里初始化即可。

kotlin 复制代码
     //上拉加载和下拉刷新,初始化头和尾
        ListConfig.apply {
            addRefreshHeader {
                ClassicsHeader(it)
            }
            addRefreshFooter {
                ClassicsFooter(it)
            }
        }

这里也简单举个例子:

1、xml中引入

xml 复制代码
  <com.abner.refresh.kernel.SmartRefreshLayout
        android:id="@+id/srl_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </com.abner.refresh.kernel.SmartRefreshLayout>

2、代码简单使用

kotlin 复制代码
mSmartRefreshLayout?.setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
            override fun onRefresh(refreshLayout: RefreshLayout) {
               
            }

            override fun onLoadMore(refreshLayout: RefreshLayout) {
             
            }
        })

当然了,为了更好的拓展使用,针对SmartRefreshLayout,又简单做了一层包装,别无他意,就是为了让使用更加的简单。

1、xml里引入PageRefreshLayout

xml 复制代码
 <com.abner.relist.PageRefreshLayout
            android:id="@+id/refresh"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

2、代码里使用

kotlin 复制代码
  mBinding.refresh.getRecycler().linear()
            .divider()
            .set<String> {
                addLayout(R.layout.layout_item, BR.str)
            }
        //刷新和加载
        mBinding.refresh.refresh { isRefresh, refreshLayout ->
            mViewModel.doHttp {
                addData(it)
            }
        }.autoRefresh()

直接调用refresh方法即可,isRefresh为true是下拉,否则就是上拉,非常的方便,而addData方法,则实现了分页加载数据,上拉和下拉直接调用addData即可。

PageRefreshLayout可调用方法如下

方法 参数 概述
autoRefresh 无参 自动刷新操作
refresh 无参 静默刷新(不带下拉刷新动画)
addData Collection<T> 添加数据,分页会自动追加数据,下拉和上拉会自动关闭
setEnableRefresh Boolean 是否禁止下拉
setEnableLoadMore Boolean 是否禁止上拉
finishRefresh 无参 关闭下拉刷新
finishLoadMore 无参 关闭上拉刷新
getPager 无参 获取当前页码
refresh 回调函数 刷新和加载方法
getSmartRefresh 无参 获取SmartRefreshLayout
getRecycler 无参 获取RecyclerView
addEmptyView Int/View 添加空的布局,支持layout和View
addErrorView Int/View 添加错误的布局,支持layout和View
showEmptyView 无参 显示空布局
showErrorView 无参 显示错误布局
hintEmptyView 无参 隐藏空布局
hintErrorView 无参 隐藏错误布局
setHeightWrapContent 无参 设置整体的列表由充满改为包裹内容。

三、开源地址

关于大家在使用上的问题以及后续的优化,或者功能新增,都会时长更新,方便的话,给个小星星呗~

开源地址:github.com/AbnerMing88...

四、使用总结

1、无适配器的模式,在逻辑相对复杂的页面,建议大家可以抽取到ViewModel中实现,当然,也可以采用DataBinding的形式。

2、很多使用方式,或者常见的业务开发场景,在文档中或者源码中,都会详细的备注,大家可以细心的查看即可。

3、条目点击事件,给出了两个,大家可以选择性使用。

只返回索引

kotlin 复制代码
setOnItemClickListener { 
                    
}

当前点击的View和索引。

kotlin 复制代码
 setOnItemViewClickListener { view, position ->
                   
 }

五、后续规划

此库的封装,除了刷新加载库使用了SmartRefreshLayout,其他的都是自己从0到1的开发,目前,自己已经在项目中使用,暂时没有出现任何问题,当然了,后续,也会不断的对其进行优化,增加一些其他的功能,希望有需要的小伙伴,长期关注。

关于维护上,不断的优化和解决一些大家所提的问题。

关于源码上,后续会逐一剖析其实现方式,确确实实,里面用到了一些另类技术,当然了,这都是后话了。

相关推荐
枯骨成佛31 分钟前
Android中Crash Debug技巧
android
kim56596 小时前
android studio 更改gradle版本方法(备忘)
android·ide·gradle·android studio
咸芝麻鱼6 小时前
Android Studio | 最新版本配置要求高,JDK运行环境不适配,导致无法启动App
android·ide·android studio
无所谓จุ๊บ6 小时前
Android Studio使用c++编写
android·c++
csucoderlee6 小时前
Android Studio的新界面New UI,怎么切换回老界面
android·ui·android studio
kim56596 小时前
各版本android studio下载地址
android·ide·android studio
饮啦冰美式6 小时前
Android Studio 将项目打包成apk文件
android·ide·android studio
夜色。7 小时前
Unity6 + Android Studio 开发环境搭建【备忘】
android·unity·android studio
ROCKY_8178 小时前
AndroidStudio-滚动视图ScrollView
android
趴菜小玩家9 小时前
使用 Gradle 插件优化 Flutter Android 插件开发中的 Flutter 依赖缺失问题
android·flutter·gradle