返回顶部
首页 > 资讯 > 精选 >BaseQuickAdapter的使用
  • 798
分享到

BaseQuickAdapter的使用

androidjavakotlin 2023-08-19 10:08:06 798人浏览 泡泡鱼
摘要

文章目录 前言一、基础使用二、分组布局和多布局1.BaseMultiItemQuickAdapter2.BaseDelegateMultiAdapter3.BaseProviderMultiAdapter4.BaseSectionQ


前言

是由BRVAH(官方网站)提供的万用适配器,相比原始的适配器,能减少70%的代码


一、基础使用

简单需求实现:一个Adapter将数据和布局与RecyclerView绑定。
创建MyAdapter并继承BaseQuickAdapter,第一个泛型对应数据类型,就是ItemBean;第二个泛型对应ViewHolder,一般直接填写BaseViewHolder即可。

inner class MyAdapter(private val layoutRes: Int) :        BaseQuickAdapter<ItemBean, BaseViewHolder>(layoutRes) {        override fun convert(holder: BaseViewHolder, item: ItemBean) {            holder.setText(R.id.textView, "${ItemBean.text}")//先获取指定组件,再设置属性        }    }

convert方法类似原始适配器中的onBindViewHolder方法,用于绑定数据、设置事件等。
定义好了适配器,需要初始化recyclerview
//这个rv该设计为高复用性

        val layoutManager = LinearLayoutManager(this)        recyclerView.layoutManager = layoutManager        recyclerView.adapter = MyAdapter(R.layout.layout_list_item)

添加头部

//添加头部尾部布局        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)

添加点击事件
点击事件的对象可以是Item条目,也可以是Item中的子控件,事件可以是点击或者长按。
添加Item子控件事件的方式有两种,一种是在Adapter的convert方法中获取控件,然后设置事件;另一种方式则与设置Item事件类似,不过需要先注册对应的控件。
第一种方式:在convert方法中设置

inner class MyAdapter(private val layoutRes: Int) :        BaseQuickAdapter<ItemBean, BaseViewHolder>(layoutRes) {        override fun convert(holder: BaseViewHolder, item: ItemBean) {            val rvClick = holder.getView<RelativeLayout>(R.id.RV)            rvClick.setOnClickListener {                //点击事件            }        }    }

第二种方式:使用adapter设置
首先注册对应控件

       adapter.addChildClickViewIds(R.id.editFORM,R.id.editFormText)

//添加点击事件

    //RecyclerView的item点击事件        adapter.setOnItemClickListener { adapter, view, position ->            onItemClick(view,position)        }        //RecyclerView的item子控件点击事件        adapter.setOnItemChildClickListener { adapter, view, position ->            onItemChildClick(view,position)        }

通过回调获取监听事件

override fun onItemChildClick(view: View, position: Int) {        when(view.id){            R.id.editForm -> {                toast("editForm点击新增事件")            }            R.id.editFormText -> {                toast("editFormText点击事件")            }        }    }

注意:监听子控件点击事件对应的是 setOnItemChildClickListener ,若添加的是setOnItemClickListener 是获取不到的。
长按点击事件类似不在叙述。

添加动画

adapter.setAnimationWithDefault(AnimationType type)

//内置默认动画类型
enum class AnimationType {
Alphain, ScaleIn, SlideInBottom, SlideInLeft, SlideInRight
}

二、分组布局和多布局

分组布局也是多布局的一种,比如分组为头布局和内容布局,而多布局则可以包含更多的布局。框架中,提供的对分组布局的解决方案是:BaseSectionQuickAdapter,提供的对多布局的解决方案有:BaseMultiIteMQuickAdapter、BaseDelegateMultiAdapterBaseProviderMultiAdapter,它们各有优势,实际使用时根据不同的设计需求合理选择即可。

1.BaseMultiItemQuickAdapter

适用于类型较少,业务不复杂的场景,便于快速使用。 使用此适配器时,数据类必须实现MultiItemEntity接口并重写getItemType方法来返回类型。
定义数据类:

class BaseMultiQuickItem(override val itemType: Int, val data: BaseQuickerItem) : MultiItemEntity {     compaNIOn object {          const val FIRST_TYPE = 1          const val SECOND_TYPE = 2     }}

有了数据类之后,就可以着手编写适配器类了。适配器先将对应的布局和类型绑定,然后在convert方法中根据类型设置数据即可。

inner class BaseQuickInfoListAdapter :        BaseMultiItemQuickAdapter<BaseMultiQuickItem, BaseViewHolder>() {        init {        //为不同类型添加不同的布局            addItemType(BaseMultiQuickItem.FIRST_TYPE, R.layout.layout_base_quick_first_item)            addItemType(BaseMultiQuickItem.SECOND_TYPE , R.layout.layout_base_quick_second_item)        }        override fun convert(holder: BaseViewHolder, itemMulti: BaseMultiQuickItem) {            //多item            when(holder.itemViewType){                BaseMultiQuickItem.FIRST_TYPE  -> {                    holder.setText(R.id.formName, "${itemMulti.data.title}")                }                BaseMultiQuickItem.SECOND_TYPE  -> {                    holder.setText(R.id.formName, "第二個布局")                }            }        }    }

最后,为RecyclerView设置适配器即可。

在这里插入图片描述

2.BaseDelegateMultiAdapter

通过代理类的方式,返回布局id和item类型。此适配器的的数据类型可以为任意类型,适用于实体类不方便拓展的情况。 实体类仍使用 BaseMultiQuickItem,直接看适配器的实现。

class DelegateMultiAdapter :        BaseDelegateMultiAdapter<BaseMultiQuickItem?, BaseViewHolder>() {        //通过convert方法设置数据        override fun convert(helper: BaseViewHolder, item: BaseMultiQuickItem?) {            when (helper.itemViewType) {                BaseMultiQuickItem.FIRST_TYPE -> helper.setText(                    R.id.editForm,                    "FIRST_TYPE"                )                BaseMultiQuickItem.SECOND_TYPE -> {                    when (helper.layoutPosition % 2) {                        0 -> helper.setText(R.id.editForm, "SECOND_TYPE 111")                        1 -> helper.setText(R.id.editForm, "SECOND_TYPE 222")                        else -> {}                    }                }                else -> {}            }        }        init {            // 1、设置代理,通过setMultiTypeDelegate方法返回类型。            setMultiTypeDelegate(object : BaseMultiTypeDelegate<BaseMultiQuickItem?>() {                override fun getItemType(data: List<BaseMultiQuickItem?>, position: Int): Int {                    // 根据数据,自己判断应该返回的类型                    when (position % 3) {                        0 -> return BaseMultiQuickItem.FIRST_TYPE                        1 -> return BaseMultiQuickItem.SECOND_TYPE                        else -> {}                    }                    return 0                }            })            //2、绑定 item 类型,通过addItemType方法将类型和布局绑定。            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方法中做大量的业务逻辑,把逻辑抽取到对应的ItemProvider中。有以下特点:
1、此适配器的数据类型可以是任意类型,只需在getItemType方法中返回类型
2、也不限定ViewHolder类型,可以在ItemProvider中自定义。
这个适配器看起来复杂,实际上就是将每种Item都抽离成为一个单独的类,然后整合到适配器中,最大化自定义ViewHolder类型,以减少适配器中的代码量。

编写适配如下,可以看到这里面的代码比较少,避免在convert方法中做大量的业务逻辑

class ProviderMultiAdapter : BaseProviderMultiAdapter<BaseMultiQuickItem?>() {                override fun getItemType(data: List<BaseMultiQuickItem?>, 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())        }    }

下面是FirstItemProvider的代码逻辑,SecondItemProvider是一样的。可以看到大量的业务逻辑,抽取到了对应的ItemProvider当中

class FirstItemProvider : BaseItemProvider<BaseMultiQuickItem?>() {    // 此item 类型    override val itemViewType: Int        get() = BaseMultiQuickItem.FIRST_TYPE    // 返回 item 布局 layout    override val layoutId: Int        get() = R.layout.layout_base_quick_first_item        override fun onCreateViewHolder(parent: ViewGroup, viewType:Int): BaseViewHolder {        return super.onCreateViewHolder(parent,viewType)    }    override fun convert(helper: BaseViewHolder, data: BaseMultiQuickItem?) {        // 设置 item 数据        if (helper.absoluteAdapterPosition % 2 === 0) {            helper.setText(R.id.formName, "第一行")        } else {            helper.setText(R.id.formName, "第二行")        }    }    // 点击 item 事件    override fun onClick(        helper: BaseViewHolder,        view: View,        data: BaseMultiQuickItem?,        position: Int    ) {        toast(context,"Click: $position")    }}

4.BaseSectionQuickAdapter

快速实现带头部的适配器,本质属于多布局,继承自BaseMultiItemQuickAdapter 使用此适配器时,需自定义类继承jsectionEntity抽象类,然后重新封装自己的数据类。
数据类编写如下:

class BaseSectionQuickItem(     override val isHeader: Boolean,      bean: BaseQuickerItem) : JSectionEntity()

适配器编写如下:

class SectionQuickAdapter(layoutResId: Int, sectionHeadResId: Int, data: MutableList<BaseSectionQuickItem>?) :        BaseSectionQuickAdapter<BaseSectionQuickItem, BaseViewHolder>(layoutResId, sectionHeadResId, data) {        override fun convert(helper: BaseViewHolder, item: BaseSectionQuickItem) {            helper.setText(R.id.editForm, "头部")        }        override fun convertHeader(helper: BaseViewHolder, item: BaseSectionQuickItem) {            helper.setText(R.id.editForm, "内容")        }    }

三、框架实现

封装万能的BaseViewHolder

//子布局中的控件    private SparseArray<View> mItemViews;    //子布局    private View mView;    //初始化ViewHolder    public BaseViewHolder(View itemView) {        super(itemView);        mView = itemView;        mItemViews = new SparseArray<>();    }        public View getView(@IdRes int viewId) {        View view = mItemViews.get(viewId);        if (view == null) {            view = mView.findViewById(viewId);            mItemViews.put(viewId, view);        }        return view;    }        public BaseViewHolder setText(@IdRes int viewId, @StringRes int resId) {        TextView textView = (TextView) getView(viewId);        textView.setText(resId);        return this;    }    public BaseViewHolder setOnClickListener(@IdRes int viewId, @NonNull View.OnClickListener            listener) {        View view = getView(viewId);        if (listener != null) {            view.setOnClickListener(listener);        }        return this;    }

主要实现:
1)使用SparseArray存储item布局中的控件,通过getView()去获取控件,如果在SparseArray中存在则直接获取,如果不存在则findViewById()然后再插入SparseArray中
2)设置一些操作方法:设置控件属性,添加点击事件等

SparseArrayHashMap更省内存,在某些条件下性能更好,主要是因为它避免了对key的自动装箱(int转为Integer类型),它内部则是通过两个数组来进行数据存储的,一个存储key,另外一个存储value,为了优化性能,它内部对数据还采取了压缩的方式来表示稀疏数组的数据,从而节约内存空间.

封装简单的BaseQuickAdapter

主要实现:
1)将重复的方法那些全部抽取到父类免得每次都重复写

onCreateViewHoldergetItemCountgetItemViewTypeonBindViewHoldergetItemgetItemPosition...
  1. 在onCreateViewHolder()里面写点击事件比较好,因为在onBindViewHolder()里面写的话,每次都要去绑定,会产生多余的消耗.
   val viewHolder = onCreateDefViewHolder(parent, viewType)       bindViewClickListener(viewHolder, viewType)
  1. 然后onBindViewHolder()方法是需要每个子类去实现的,我们可以提供一个convert()方法在里面,暴露给外面实现,用于绑定数据.
override fun onBindViewHolder(holder: VH, position: Int, payloads: MutableList<Any>) {        if (payloads.isEmpty()) {            onBindViewHolder(holder, position)            return        }        //Add up fetch logic, almost like load more, but simpler.        mUpFetchModule?.autoUpFetch(position)        //Do not move position, need to change before LoadMoreView binding        mLoadMoreModule?.autoLoadMore(position)        when (holder.itemViewType) {            LOAD_MORE_VIEW -> {                mLoadMoreModule?.let {                    it.loadMoreView.convert(holder, position, it.loadMoreStatus)                }            }            HEADER_VIEW, EMPTY_VIEW, FOOTER_VIEW -> return            else -> convert(holder, getItem(position - headerLayoutCount), payloads)        }    }
  1. 封装添加item,移除方法
open fun setList(list: Collection<T>?) //使用新的数据集合open fun setData(@IntRange(from = 0) index: Int, data: T) //改变某一位置数据open fun aDDData(@IntRange(from = 0) position: Int, data: T) //在指定位置添加一条新数据open fun addData(@IntRange(from = 0) position: Int, newData: Collection<T>) //在指定位置添加数据

移除类似
5) 封装item点击事件
包含条目和子控件的监听事件

fun setOnItemClickListener(listener: OnItemClickListener?) {        this.mOnItemClickListener = listener    }    ...........    fun getOnItemClickListener(): OnItemClickListener? = mOnItemClickListener    ...........

来源地址:https://blog.csdn.net/qq_40348833/article/details/125522050

--结束END--

本文标题: BaseQuickAdapter的使用

本文链接: https://lsjlt.com/news/375287.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • BaseQuickAdapter的使用
    文章目录 前言一、基础使用二、分组布局和多布局1.BaseMultiItemQuickAdapter2.BaseDelegateMultiAdapter3.BaseProviderMultiAdapter4.BaseSectionQ...
    99+
    2023-08-19
    android java kotlin
  • 【Android】BaseQuickAdapter使用(RecyclerView万能适配器)
    目录 前言一、导入依赖二、适配器比较三、基础使用四、多布局和分组布局1.BaseMultiItemQuickAdapter2.BaseDelegateMultiAdapter3.BasePro...
    99+
    2023-10-26
    android kotlin android studio
  • Pillow使用Image篇的使用
    目录安装Pillow构建图像图像对象图像对象属性安装Pillow pip install pillow 构建图像 Image.open(fp, mode ='r' ):打开图片...
    99+
    2024-04-02
  • Impala的使用
    什么是Impala 用来处理存储在Hadoop集群中大量数据的大规模并行处理的sql查询引擎,它是由C++和Java编写的开源软件,它提供了访问Hadoop中分布式文件系统中的数据的最快的方法。 Impalade优点 使用Impala,与...
    99+
    2015-03-31
    Impala的使用
  • dblink的使用
    1.创建全局link(使用本地一个用户访问其它用户的表)语法: create public database link 链接名  CONNECT TO 本地用户名 IDENTIFIED BY 密码...
    99+
    2024-04-02
  • Logminer的使用
    [oracle@db12c ~]$ mkdir utl_file_dir[oracle@db12c ~]$ sqlplus / as sysdbaSQL*Plus: Release 12.1.0.2.0 P...
    99+
    2024-04-02
  • pandasdf.sample()的使用
    sample()函数常用来随机获取dataFrame中数据,可以用于快速查看。 常用的有以下入参: n :指定获取的数量,默认为1axis:指定随机获取的是行还是列。0表示行,1表示...
    99+
    2024-04-02
  • Altium_Designer的使用
    内容包括原理图、PCB图绘制方法,封装制作以及DRC规则的使用、图纸的打印、出错处理,3D元件体建立教程及相应的3D封装下载等。紫色文字是超链接,点击自动跳转至相关博文。持续更新,原创不易! 目录: 一、一般介绍 1、中文显示 2、修改PC...
    99+
    2023-09-15
    AD的使用
  • GDB的使用
    目录 1. 什么是gdb 2. gdb的使用 2.1 生成调试信息 2.2 gdb的基本用法 2.2.1 启动gdb 2.2.2 gdb退出 2.2.3 列出源码 2.2.4 运行程序 2.2.5 断点 2.2.6 逐过程调试和单步调试  ...
    99+
    2023-09-25
    linux 服务器
  • window.dialogArguments的使用
    window.dialogArguments是一个只读属性,它返回对话框的参数。在JavaScript中,当使用window.sho...
    99+
    2023-09-12
    使用
  • CompletableFuture的使用
    目录 一、前言 二、概念介绍  三、自身特性 四、使用方式 1、异步执行一个任务并获取结果 2、异步执行一个任务并处理异常 3、异步执行多个任务并合并结果 4、异步执行多个任务并处理其中一个任务的结果 5、串行执行多个任务 6、 检查异步任...
    99+
    2023-09-01
    java
  • pip的使用
    目录 ❤  配置pip环境变量 ❤  Cmd终端使用pip ❤  Pycharm使用pip ❤  Jupyter使用pip python从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959...
    99+
    2023-10-23
    pip python 开发语言 pycharm
  • mapper的使用
    一、通用mapper概述 它是mybatis的一个插件,单表查询的时候,使用通用mapper会非常的方便。极大地方便开发人员,可以按照需要选择通用方法,还可以自定义通用方法。不过它也有一个非常大的局限性:只支持单表操作,不支持多表查询。 ...
    99+
    2023-10-18
    mybatis java mysql Powered by 金山文档
  • MongoDB的使用
    今天来学习一个新的数据库,叫做MongoDB数据库,我们先来了解一下MongoDB数据库的概念,再一起学习如何使用MongoDB数据库吧~MongoDB的概念MongoDB是专为可扩展性、高性能和高可用性而设计的数据库,MongoDB的库中...
    99+
    2023-06-02
  • jsoup的使用
    本文在写作过程中参考了官方文档,传送门。 一、jsoup概述   jsoup 是一款基于 Java 的HTML解析器,它提供了一套非常省力的API,不但能直接解析某个URL地址、HTML文本内容,而且还能通过类似于DOM、CSS或者j...
    99+
    2023-08-20
    前端 java 开发语言
  • iframe的使用用法
    标签用于在当前 HTML 文档中嵌入另一个 HTML 文档。它创建了一个包含另一个文档的内联框架。以下是 标签的使用方法:1. ...
    99+
    2023-09-21
    iframe
  • tts使用的resource.irf文件如何使用
    tts使用的resource.irf文件是一种语音合成引擎使用的资源文件,包含了音素、声韵对应关系、音频特征等信息,用于将文本转化为...
    99+
    2023-09-08
    tts
  • IOS使用TestFlight测试的使用方法
    目录一、testflight优势二、开发人员TestFlight的设置操作步骤三、测试人员TestFlight的使用步骤现在最主流的移动端操作系统就是 Android 和 iOS ,...
    99+
    2022-12-17
    TestFlight测试 TestFlight
  • Python的@property的使用
    目录1、几个概念2、举个例子3、解决问题4、换个方法通常,当我们需要对对象的敏感属性或者不希望外部直接访问的属性进行私有化,但是某些时候我们又需要对这些私有属性进行修改,该怎么处理呢...
    99+
    2024-04-02
  • React中setState的使用与同步异步的使用
    在react中,修改状态如果直接使用this.state,不会引起组件的重新渲染,需要通过 this.setState来对组件的属性进行修改。 1、this.setState的两种...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作