目录

1,简述

2,简单使用记录

1,引入依赖,目前作者已更新到v4版本,一句代码即可引入

2,Adapter类型

        1,BaseQuickAdapter 基础类型 Adapter(包含点击事件、数据操作、动画、空视图)

        2,BaseMultiItemAdapter多类型布局 Adapter

        3,BaseDifferAdapter (Differ Adapter)

1,数据对象注意事项

2,实现 DiffUtil.ItemCallback 类,用于进行新老数据对比,进行精准刷新

3,Adapter 的编写与 BaseQuickAdapter 一致

 4,BaseSingleItemAdapter 只有单个 item 情况下的 Adapter

5,QuickAdapterHelper 多类型 Adapter 组合(包含“加载更多”、“头部”、“尾部”)

1,QuickAdapterHelper 基础

2,QuickAdapterHelper 功能

3,点击事件

4,数据操作 


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看作者的源码

参考:https://github.com/CymChad

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐