BaseRecyclerViewAdapterHelper 简单使用记录
1,BaseRcycleViewAdapterHelper 是一个强大而灵活的RecyclerView Adapter库,支持单布局,多布局,分组布局,空布局,添加头部,添加尾部,支持拖拽、滑动、删除,此外还有加载动画效果等。新旧数据的差异化对比是异步的,不会导致UI阻塞,不仅适合常用列表,也适合超大数据列表、超频繁的数据刷新列表(例如:股票实时涨跌列表)进行组合,从而实现“向上加载”、“向下加载
目录
1,BaseQuickAdapter 基础类型 Adapter(包含点击事件、数据操作、动画、空视图)
2,BaseMultiItemAdapter多类型布局 Adapter
3,BaseDifferAdapter (Differ Adapter)
2,实现 DiffUtil.ItemCallback 类,用于进行新老数据对比,进行精准刷新
3,Adapter 的编写与 BaseQuickAdapter 一致
4,BaseSingleItemAdapter 只有单个 item 情况下的 Adapter
5,QuickAdapterHelper 多类型 Adapter 组合(包含“加载更多”、“头部”、“尾部”)
1,简述
1,BaseRcycleViewAdapterHelper 是一个强大而灵活的RecyclerView Adapter库,支持单布局,多布局,分组布局,空布局,添加头部,添加尾部,支持拖拽、滑动、删除,此外还有加载动画效果等。
2,地址:gitHub 源码地址
2,简单使用记录
1,引入依赖,目前作者已更新到v4版本,一句代码即可引入
implementation "io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.1.4"
2,Adapter类型
1,BaseQuickAdapter 基础类型 Adapter(包含点击事件、数据操作、动画、空视图)
class TopAdapter : BaseQuickAdapter<TopItem, TopAdapter.VH>() {
// 自定义ViewHolder类
class VH(val bind: ItemTopBinding) : RecyclerView.ViewHolder(bind.root)
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
// 返回一个 ViewHolder
val binding = ItemTopBinding.inflate( LayoutInflater.from(context),
parent,
false)
return VH(binding)
}
override fun onBindViewHolder(holder: VH, position: Int, item: Status?) {
// 设置item数据
holder.bind.topItemTv.text = item?.txt
}
}
如果你的Adapter特别简单,不想用ViewBinding,自己也不想写ViewHolder,可以使用QuickViewHolder
class TestAdapter : BaseQuickAdapter<Status, QuickViewHolder>() {
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): QuickViewHolder {
// 返回一个 ViewHolder
return QuickViewHolder(R.layout.layout_animation, parent)
}
override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: Status?) {
// 设置item数据
holder.getView(R.id.xxxx)
}
}
2,BaseMultiItemAdapter多类型布局 Adapter
此类型用于实现简单的多类型布局。
方法一 先用addItemType()添加Item类型,再调用onItemViewType()确定数据对应的ItemViewType。
class TestAdapter(data: List<HomeEntity>) : BaseMultiItemAdapter<HomeEntity>(data) { // 类型 1 的 viewholder class ItemVH(val viewBinding: HomeItemViewBinding) : RecyclerView.ViewHolder(viewBinding.root) // 类型 2 的 viewholder class HeaderVH(val viewBinding: DefSectionHeadBinding) : RecyclerView.ViewHolder(viewBinding.root) // 在 init 初始化的时候,添加多类型 init { addItemType(ITEM_TYPE, object : OnMultiItemAdapterListener<HomeEntity, ItemVH> { // 类型 1 override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): ItemVH { // 创建 viewholder val viewBinding = HomeItemViewBinding.inflate(LayoutInflater.from(context), parent, false) return ItemVH(viewBinding) } override fun onBind(holder: ItemVH, position: Int, item: HomeEntity?) { // 绑定 item 数据 } }).addItemType(SECTION_TYPE, object : OnMultiItemAdapterListener<HomeEntity, HeaderVH> { // 类型 2 override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): HeaderVH { // 创建 viewholder val viewBinding = DefSectionHeadBinding.inflate(LayoutInflater.from(context), parent, false) return HeaderVH(viewBinding) } override fun onBind(holder: HeaderVH, position: Int, item: HomeEntity?) { // 绑定 item 数据 } override fun isFullSpanItem(itemType: Int): Boolean { // 使用GridLayoutManager时,此类型的 item 是否是满跨度 return true; } }).onItemViewType { position, list -> // 根据数据,返回对应的 ItemViewType if (list[position].isSection) { SECTION_TYPE } else { ITEM_TYPE } } } companion object { private const val ITEM_TYPE = 0 private const val SECTION_TYPE = 1 } }
- 方法二 Adapter 类中不写,在外部注册。原理一致.
adapter.addItemType(ITEM_TYPE, object : OnMultiItemAdapterListener<HomeEntity, ItemVH> { // 类型 1 override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): ItemVH { // 创建 viewholder val viewBinding = HomeItemViewBinding.inflate(LayoutInflater.from(context), parent, false) return ItemVH(viewBinding) } override fun onBind(holder: ItemVH, position: Int, item: HomeEntity?) { // 绑定 item 数据 } }).onItemViewType { position, list -> // 根据数据,返回对应的 ItemViewType if (list[position].isSection) { SECTION_TYPE } else { ITEM_TYPE } }
3,BaseDifferAdapter (Differ Adapter)
此类使用Differ方式来管理数据,进行数据的局部刷新。新旧数据的差异化对比是异步的,不会导致UI阻塞,不仅适合常用列表,也适合超大数据列表、超频繁的数据刷新列表(例如:股票实时涨跌列表)
1,数据对象注意事项
Java 编写的数据类型,需要实现equals()方法
public class Entity { ... @Override public boolean equals(Object o) { // 实现此系统方法 } }
kotlin 编写的数据类型,需要是 data class 类型就行了。
data class Entity(val test: String) { }
2,实现 DiffUtil.ItemCallback<T> 类,用于进行新老数据对比,进行精准刷新
class EntityDiffCallback: DiffUtil.ItemCallback<DiffEntity>() { override fun areItemsTheSame(oldItem: DiffEntity, newItem: DiffEntity): Boolean { // 判断是否是同一个 item(通常使用id字段判断) } override fun areContentsTheSame(oldItem: DiffEntity, newItem: DiffEntity): Boolean { // 如果是同一个item,则判断item内的数据内容是否有变化 } override fun getChangePayload(oldItem: DiffEntity, newItem: DiffEntity): Any? { // 可选实现 } }
3,Adapter 的编写与 BaseQuickAdapter 一致
class TestAdapter :BaseDifferAdapter<DiffEntity, QuickViewHolder>(EntityDiffCallback()) { override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): QuickViewHolder { // 创建 ViewHolder return QuickViewHolder(R.layout.layout_animation, parent) } override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: DiffEntity?) { // 设置 item 数据 } }
4,BaseSingleItemAdapter 只有单个 item 情况下的 Adapter
只有单个 item 情况下的 Adapter。此类用作特别用途,例如:头部HeaderAdapter、尾部FooterAdapter等情况。()
class HeaderAdapter: BaseSingleItemAdapter<Any, HeaderAdapter.VH>() { class VH(view: View): RecyclerView.ViewHolder(view) override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { val view = LayoutInflater.from(parent.context).inflate(R.layout.head_view, parent, false) return VH(view) } override fun onBindViewHolder(holder: VH, item: Any?) { // 可以在此绑定数据 } } /**由于只有单item,所有没有add、remove等操作。*/ // 设置数据 adapter.item = data // payload 方式刷新数据 adapter.setItem(data, payload)
5,QuickAdapterHelper 多类型 Adapter 组合(包含“加载更多”、“头部”、“尾部”)
此类的本质是使用 ConcatAdapter 进行组合,从而实现“向上加载”、“向下加载”、“头部”、“尾部”的功能。
通过此工具类包装以后,可以得到一个对外的adapter,用于设置给RecyclerView。
1,QuickAdapterHelper 基础
此类必须通过使用 Build 来构建,必须传递你的列表adapter,build时包含Api如下
// 使用 Builder 创建 QuickAdapterHelper 对象,这里需要传入你的列表 mAdapter val helper = QuickAdapterHelper.Builder(mAdapter) // 设置尾部"加载更多" .setTrailingLoadStateAdapter(……) // 设置首部“加载更多” .setLeadingLoadStateAdapter(……) // 设置 ConcatAdapter 的配置 .setConfig(……) .build() // 注意⚠️:RecyclerView 必须使用 helper 提供的 adapter recyclerView.adapter = helper.adapter
2,QuickAdapterHelper 功能
QuickAdapterHelper内部已经有了你的列表mAdapter,据此为原点,提供以下功能:
// 在 mAdapter 前面,添加其他 adapter fun addBeforeAdapter(adapter: BaseQuickAdapter<*, *>) // 在 mAdapter 后面,添加其他 adapter fun addAfterAdapter(adapter: BaseQuickAdapter<*, *>) // 移除一个 adapter fun removeAdapter(adapter: BaseQuickAdapter<*, *>) // 清理 mAdapter 前面的所有 Adapter fun clearBeforeAdapters() // 清理 mAdapter 后面的所有 Adapter fun clearAfterAdapters()
3,点击事件
//item 点击事件
adapter.setOnItemClickListener { adapter, view, position ->
Tips.show("onItemClick $position")
}
//item 长按事件
adapter.setOnItemLongClickListener { adapter, view, position ->
Tips.show("onItemLongClick $position")
true
}
//item 子控件点击事件
// 需要传递控件 id
adapter.addOnItemChildClickListener(R.id.iv_num_add) { adapter, view, position ->
Tips.show("onItemChildClick: add $position")
}
//item 子控件长按事件
// 需要传递控件 id
adapter.addOnItemChildLongClickListener(R.id.btn_long) { adapter, view, position ->
Tips.show("onItemChildLongClick $position")
true
}
点击事件 扩展
去除点击抖动(双击)的点击方法。 默认500毫秒间隔,可以传递参数修改。
// item 去除点击抖动的扩展方法
adapter.setOnDebouncedItemClick { adapter, view, position ->
}
// item Child 去除点击抖动的扩展方法
adapter.addOnDebouncedChildClick { adapter, view, position ->
}
4,数据操作
/**设置数据集合*/
adapter.submitList(list)
/**修改某一位置的数据*/
//修改index为1处的数据
adapter[1] = data
/** 新增数据**/
// 尾部新增数据
adapter.add(data)
// 在指定位置添加一条新数据
adapter.add(1, data)
// 添加数据集
adapter.addAll(list)
// 指定位置添加数据集
adapter.addAll(1, list)
/**删除数据**/
// 删除数据
adapter.remove(data)
// 删除指定位置数据
adapter.removeAt(1)
5,添加动画
1,设置默认动画
/**
* BaseQuickAdapter.AnimationType.AlphaIn 渐显
* BaseQuickAdapter.AnimationType.ScaleIn 缩放
* BaseQuickAdapter.AnimationType.SlideInBottom 从下到上
* BaseQuickAdapter.AnimationType.SlideInLeft 从左到右
* BaseQuickAdapter.AnimationType.SlideInRight 从右到左
*/
adapter.setItemAnimation(BaseQuickAdapter.AnimationType.AlphaIn)
2,自定义动画
需继承 ItemAnimator 实现自定义动画
class CustomAnimation1 : ItemAnimator {
override fun animator(view: View): Animator {
// 创建三个动画
val alpha: Animator = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f)
val scaleY: Animator = ObjectAnimator.ofFloat(view, "scaleY", 1.3f, 1f)
val scaleX: Animator = ObjectAnimator.ofFloat(view, "scaleX", 1.3f, 1f)
scaleY.interpolator = DecelerateInterpolator()
scaleX.interpolator = DecelerateInterpolator()
// 多个动画组合,可以使用 AnimatorSet 包装
val animatorSet = AnimatorSet()
animatorSet.duration = 350
animatorSet.play(alpha).with(scaleX).with(scaleY)
return animatorSet
}
}
// 设置动画
adapter.itemAnimation = CustomAnimation1()
结言:目前只整理了部分基础用法,更多内容请到GitHub看作者的源码
更多推荐


所有评论(0)