【Android】BaseQuickAdapter使用(RecyclerView万能适配器)
目录
- 前言
- 一、导入依赖
- 二、适配器比较
- 三、基础使用
- 四、多布局和分组布局
- 1.BaseMultiItemQuickAdapter
- 2.BaseDelegateMultiAdapter
- 3.BaseProviderMultiAdapter
- 4.BaseSectionQuickAdapter
- 总结
前言
RecyclerView是Android用于取代ListView的SDK,它的灵活性和可替代性都比ListView更好,但RecyclerView也存在一些问题: 高度不能自适应、最后一个 Item 显示不全被遮挡等。而无论ListView还是RecyclerView都必不可少地会使用到适配器,其配置比较繁琐。
(图片来源网络,侵删)BaseQuickAdapter 可以对繁琐的适配器进行快速构建,相比原始的RecyclerView.Adapter适配器,能减少70%以上的代码。
本文将使用Kotlin语言来编写,Kotlin作为安卓板块的新语言,集大家之所长,一定程度上提高了开发效率,后续会有介绍。
BRVAH官方使用指南:BRVAH官方使用指南
一、导入依赖
在 build.gradle(Module:app) 的 dependencies 添加:
dependencies { implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4' }
二、适配器比较
- 原始的 RecyclerView.Adapter:
class RecyclerAdapter(private val context: Context, private val data: List) : RecyclerView.Adapter() { override fun getItemCount(): Int = data.size override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder?{ return MyRecyclerViewHolder(LayoutInflater.from(context) .inflate(R.layout.item_recycler, parent, false)) } //override fun getItemViewType(position: Int): Int{} override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) { holder.textView.text = "" holder.textView.setOnClickListener {} } inner class MyRecyclerViewHolder(view: View) : RecyclerView.ViewHolder(view) { var textView: TextView = view.findViewById(R.id.item_tv) } }
原始的 RecyclerView.Adapter 需要编写4~5个方法:
1、getItemCount
2、onCreateViewHolder
3、getItemViewType
4、onBindViewHolder
5、MyRecyclerViewHolder自定义ViewHolder
- BaseQuickAdapter适配器:
class MyAdapter(private val layoutRes: Int) : BaseQuickAdapter(layoutRes) { override fun convert(holder: BaseViewHolder, item: String) { holder.setText(R.id.textView, item) } }
只需要继承BaseQuickAdapter,第一个泛型对应数据类型ItemBean,第二个泛型对应ViewHolder,一般直接填写BaseViewHolder。
然后在convert方法(类似onBindViewHolder方法)中绑定数据、设置事件等,这样只需要编写一个方法即可完成大量的适配工作。
三、基础使用
- 添加到 RecycleView
val layoutManager = LinearLayoutManager(this) recyclerView.layoutManager = layoutManager val adapter=MyAdapter(R.layout.item_recycler) recyclerView.adapter = adapter
- 赋值并刷新
adapter.setNewInstance(data) //或者setNewData(),初始化数据 adapter.setList(data) //更新数据
- holder常用方法
holder.getView(viewId) //获取控件 holder.setText(R.id.textView, str) //设置文本 holder.getView(viewId).setOnClickListener {} //指定控件的点击事件 holder.getLayoutPosition() //获取当前item的position
- 外部添加点击事件
//item整体点击事件 adapter.setOnItemClickListener { adapter, view, position -> onItemClick(view,position) } //注册item对应子控件 adapter.addChildClickViewIds(R.id.item_tv) //item子控件点击事件 adapter.setOnItemChildClickListener { adapter, view, position -> onItemChildClick(view,position) }
- 添加动画
adapter.setAnimationWithDefault(type) //默认的AnimationType类型:AlphaIn, ScaleIn, SlideInBottom, SlideInLeft, SlideInRight
- 添加头部、尾部、空布局
//添加头部、尾部、空布局 val footView: View = LayoutInflater.from(this).inflate(R.layout.layout_foot, recyclerView, false) adapter.setFooterView(footView) val headView: View = LayoutInflater.from(this).inflate(R.layout.layout_head, recyclerView, false) adapter.setHeaderView(headView) val emptyView: View = LayoutInflater.from(this).inflate(R.layout.layout_empty, recyclerView, false) adapter.setEmptyView(emptyView)
- 刷新加载相关
//打开或关闭上拉加载 adapter.setEnableLoadMore(boolean) // 滑动最后一个Item的时候回调onLoadMoreRequested方法 adapter.setOnLoadMoreListener(requestLoadMoreListener) //加载完成 adapter.loadMoreComplete(); //加载失败 adapter.loadMoreFail(); //加载结束 adapter.loadMoreEnd(); //设置自定义加载布局 adapter.setLoadMoreView(CustomLoadMoreView()) //如果上拉结束后,下拉刷新需要再次开启上拉监听,需要使用setNewData方法填充数据 //-------------------- //打开或关闭下拉刷新 adapter.setUpFetchEnable(true) //设置刷新监听 adapter.setUpFetchListener(BaseQuickAdapter.UpFetchListener(){}) //设置开始加载的位置 adapter.setStartUpFetchPosition(2)
- 添加拖拽、滑动删除
val adapter = ItemDragAdapter(mData) // adapter 需要继承 BaseItemDraggableAdapter val itemDragAndSwipeCallback = ItemDragAndSwipeCallback(adapter) //拖拽和删除回调 val itemTouchHelper = ItemTouchHelper(itemDragAndSwipeCallback) itemTouchHelper.attachToRecyclerView(recyclerView) //绑定 recycleView // 开启拖拽 adapter.enableDragItem(itemTouchHelper, R.id.item_tv, true) adapter.setOnItemDragListener(onItemDragListener) //实现 OnItemDragListener 接口 // 开启滑动删除 adapter.enableSwipeItem() adapter.setOnItemSwipeListener(onItemSwipeListener) //实现 OnItemSwipeListener 接口
-------------------修订内容:2023-5-15 ----------------------
最新版本已经找不到 BaseItemDraggableAdapter 类了,不知道为什么。
解决办法:第二和第三种后续会在我的博客更新如何使用,配置都比较简单的,百度也能找到
第一种办法:将版本号换成:2.9.30,但是 3.0.4 和 2.9.30 部分类包位置有改动,而且使用写法也有不同,若以前使用过,换版本的话需要对以前的代码全部进行修改
第二种办法:手动实现 RecyclerView 的 ItemTouchHelper 的回调
第三种办法:只是实现侧滑功能,可以使用第三方包:com.mcxtzhang.swipemenulib.SwipeMenuLayout
四、多布局和分组布局
- 分组布局继承类:
BaseSectionQuickAdapter:快速实现带头部的适配器
- 多布局继承类:根据需求选择
BaseMultiItemQuickAdapter:适用于类型较少,业务不复杂的场景,便于快速使用
BaseDelegateMultiAdapter:数据类型任意,代理类方式,适用于实体类不方便拓展
BaseProviderMultiAdapter:数据类型任意,不限定ViewHolder类型,单独的自定义ViewHolder类,避免在convert方法中做大量的业务逻辑
1.BaseMultiItemQuickAdapter
数据类必须实现MultiItemEntity接口,需要给每一个数据设置itemType。
class BaseMultiQuickItem(override val itemType: Int, val data: BaseQuickerItem) : MultiItemEntity { companion object { const val FIRST_TYPE = 1 const val SECOND_TYPE = 2 } }
适配器重写getItemType方法来返回不同的数据类型。
inner class BaseQuickInfoListAdapter : BaseMultiItemQuickAdapter() { init { addItemType(BaseMultiQuickItem.FIRST_TYPE, R.layout.layout_first_item) addItemType(BaseMultiQuickItem.SECOND_TYPE , R.layout.layout_second_item) } override fun convert(holder: BaseViewHolder, itemMulti: BaseMultiQuickItem) { when(holder.itemViewType){ BaseMultiQuickItem.FIRST_TYPE -> { holder.setText(R.id.item_tv, "布局一") } BaseMultiQuickItem.SECOND_TYPE -> { holder.setText(R.id.item_tv, "布局二") } } } }
2.BaseDelegateMultiAdapter
使用代理类的方式,返回布局id和item类型,数据类依然使用 BaseMultiQuickItem。
class DelegateMultiAdapter : BaseDelegateMultiAdapter() { override fun convert(helper: BaseViewHolder, item: BaseMultiQuickItem?) { when (helper.itemViewType) { BaseMultiQuickItem.FIRST_TYPE -> helper.setText(R.id.item_tv,"布局一") BaseMultiQuickItem.SECOND_TYPE -> { when (helper.layoutPosition % 2) { 0 -> helper.setText(R.id.item_tv, "布局二 第一种") 1 -> helper.setText(R.id.item_tv, "布局二 第二种") else -> {} } } else -> {} } } init { //设置代理,通过内部类返回类型 setMultiTypeDelegate(object : BaseMultiTypeDelegate() { override fun getItemType(data: List, position: Int):Int { when (position % 3) { 0 -> return BaseMultiQuickItem.FIRST_TYPE 1 -> return BaseMultiQuickItem.SECOND_TYPE else -> {} } return 0 } }) //将类型和布局绑定 getMultiTypeDelegate() ?.addItemType(BaseMultiQuickItem.FIRST_TYPE, R.layout.layout_base_quick_first_item) ?.addItemType(BaseMultiQuickItem.SECOND_TYPE, R.layout.layout_base_quick_second_item) } }
3.BaseProviderMultiAdapter
当有多种条目时,避免在convert方法中做大量的业务逻辑,将每种Item都分离成一个个单独的类,然后整合到适配器中,最大化自定义数据类型。
class ProviderMultiAdapter : BaseProviderMultiAdapter() { override fun getItemType(data: List, position: Int): Int { when (position % 3) { 0 -> return BaseMultiQuickItem.FIRST_TYPE 1 -> return BaseMultiQuickItem.SECOND_TYPE else -> {} } return 0 } init { // 注册 Provider addItemProvider(FirstItemProvider()) addItemProvider(SecondItemProvider()) } }
把大量的业务逻辑抽取到了对应的ItemProvider中。
class FirstItemProvider : BaseItemProvider() { override val itemViewType: Int get() = BaseMultiQuickItem.FIRST_TYPE override val layoutId: Int get() = R.layout.layout_first_item //可返回自定义的 ViewHolder override fun onCreateViewHolder(parent: ViewGroup, viewType:Int): BaseViewHolder { return super.onCreateViewHolder(parent,viewType) } override fun convert(helper: BaseViewHolder, data: BaseMultiQuickItem?) { if (helper.absoluteAdapterPosition % 2 === 0) { helper.setText(R.id.item_tv, "") } else { helper.setText(R.id.item_tv, "") } } override fun onClick( helper: BaseViewHolder, view: View, data: BaseMultiQuickItem?, position: Int ) {} }
4.BaseSectionQuickAdapter
数据类需继承SectionEntity抽象类。
class BaseSectionQuickItem( override val isHeader: Boolean, bean: BaseQuickerItem ) : SectionEntity()
适配器:
class SectionQuickAdapter(layoutResId: Int, sectionHeadResId: Int, data: MutableList?) : BaseSectionQuickAdapter(layoutResId, sectionHeadResId, data) { override fun convert(helper: BaseViewHolder, item: BaseSectionQuickItem) { } override fun convertHeader(helper: BaseViewHolder, item: BaseSectionQuickItem) { } }
总结
BaseQuickAdapter功能强大,可以实现多布局、上拉刷新、下拉加载、侧滑删除、甚至树状列表等功能,且方便快捷,如果想要提高开发效率,适配器优先推荐使用它。这里可能介绍不全,详细的可参考官方文档。
五一假期的第一天,被迫码字和学习😭
- 多布局继承类:根据需求选择