YCGroupAdapter

  • 01.前沿说明

    • 1.1 案例展示效果
    • 1.2 该库功能和优势
    • 1.3 相关类介绍说明
  • 02.如何使用
    • 2.1 如何引入
    • 2.2 最简单使用
    • 2.3 使用建议
  • 03.常用api
    • 3.1 自定义adapter
    • 3.2 notify相关
    • 3.3 点击事件listener
  • 04.实现步骤
    • 4.1 业务需求分析
    • 4.2 adapter实现多type
    • 4.3 这样写的弊端
    • 4.4 分组实体bean
    • 4.5 构建封装adapter
  • 05.优化相关
  • 06.关于参考
  • 07.其他说明介绍

01.前沿说明

1.1 案例展示效果

  • demo中的效果图
  •       
  • 实际项目中的效果图
  •  

1.2 该库功能和优势

  • 按组划分的自定义adapter适配器,一个recyclerView可以完成强大的group+children类型的业务需求。
  • 每组支持添加header,footer,children,且每一个都支持设置多类型type的view视图。
  • 支持局部插入刷新,局部移除刷新,也就是说可以按组插入或者移除数据,或者按组中child的某个未知插入或者移除数据。
  • 支持组中header,footer,child的各个视图view的自定义点击事件。且返回具体的索引!
  • 常见使用场景:仿懂车帝,汽车之家分组图片查看器;仿QQ联系人分组,可以折叠和伸展;以及复杂分组页面……
  • 添加了object同步锁处理adapter中data添加,获取和移除等方法,有效避免多线程或者其他操作导致数据错位或者偶发性fast-fail。

02.如何使用

2.1 如何引入

  • 如下所示

2.2 最简单使用

  • 必须的三个步骤代码,如下所示

  • 关于如何实现仿照QQ分组的功能

03.常用api

3.1 自定义adapter

  • 代码如下所示

  • 那么如何控制组中的header或者footer是否显示呢?
    • 返回true表示显示,返回false表示不显示……就是这么简单

3.2 notify相关

  • 插入数据

  • 移除数据

3.3 点击事件listener

  • 设置组header点击事件

  • 设置组footer点击事件
  • 设置组中children点击事件

04.实现步骤

4.1 业务需求分析

  • 比如在app开发中,产品说实现一个QQ分组的功能,要求有收叠功能。同时在app中,图片相册,仿照懂车帝实现分组图片。看到这样一个需求,思考能否用一个recyclerView实现,使用type来区分不同类型布局。
  • RecyclerView 可以用ViewType来区分不同的item,也可以满足需求,但还是存在一些问题,比如:
    • 1,在item过多逻辑复杂列表界面,Adapter里面的代码量庞大,逻辑复杂,后期难以维护。
    • 2,每次增加一个列表都需要增加一个Adapter,重复搬砖,效率低下。
    • 3,无法复用adapter,假如有多个页面有多个type,那么就要写多个adapter。
    • 4,要是有局部刷新,那么就比较麻烦了,比如广告区也是一个九宫格的RecyclerView,点击局部刷新当前数据,比较麻烦。

4.2 adapter实现多个type

  • 通常写一个多Item列表的方法

    • 根据不同的ViewType 处理不同的item,如果逻辑复杂,这个类的代码量是很庞大的。如果版本迭代添加新的需求,修改代码很麻烦,后期维护困难。
  • 主要操作步骤
    • 在onCreateViewHolder中根据viewType参数,也就是getItemViewType的返回值来判断需要创建的ViewHolder类型
    • 在onBindViewHolder方法中对ViewHolder的具体类型进行判断,分别为不同类型的ViewHolder进行绑定数据与逻辑处理
  • 代码如下所示

4.3 这样写的弊端

  • 上面那样写的弊端

    • 类型检查与类型转型,由于在onCreateViewHolder根据不同类型创建了不同的ViewHolder,所以在onBindViewHolder需要针对不同类型的ViewHolder进行数据绑定与逻辑处理,这导致需要通过instanceof对ViewHolder进行类型检查与类型转型。
    • 不利于维护,这点应该是上一点的延伸,随着列表中布局类型的增加与变更,getItemViewType、onCreateViewHolder、onBindViewHolder中的代码都需要变更或增加,Adapter 中的代码会变得臃肿与混乱,增加了代码的维护成本。
    • 比如,在分组控件中,类似QQ分组那样,点击组中的header,可以切换关闭和伸展该组中children的自选项item,那么如果不封装,adapter对数据处理也比较麻烦。
    • 有时候,在分组控件中,有的组不想显示header,有的组不想显示footer,那么这个时候就不太灵活。能否使用一个开关方法来控制header和footer的显示和隐藏呢?

4.4 分组实体bean

  • 通过GroupStructure记录每个组是否有头部,是否有尾部和子项的数量。从而能方便的计算列表的长度和每个组的组头、组尾和子项在列表中的位置。

4.5 构建封装adapter

  • 核心目的就是三个

    • 避免类的类型检查与类型转型
    • 增强Adapter的扩展性
    • 增强Adapter的可维护性
  • 当列表中类型增加或减少时Adapter中主要改动的就是getItemViewType、onCreateViewHolder、onBindViewHolder这三个方法,因此,我们就从这三个方法中开始着手。
  • 在getItemViewType方法中。
    • if之类的逻辑判断简化代码,可以简单粗暴的用作为TYPE_HEADER,TYPE_FOOTER,TYPE_CHILD增加type标识。
    • 既然是分组adapter,首先是获取组的索引,然后通过组的索引来判断type的类型,最后在返回具体的itemType类型。
  • 在onCreateViewHolder方法中
    • 创建viewHolder,主要作用是创建Item视图,并返回相应的ViewHolder。这个地方,需要注意一下,在分组控件中,能否把组的header,footer,children等布局暴露给外部开发者创建?
    • 因此,这里需要区分类型,然后返回对应的布局,这里返回对应的布局几个方法,可以弄成抽象的方法,子类必须实现。让子类返回具体的header,footer,children布局。
  • 在onBindViewHolder方法中
    • 这个方法中主要做两个事情,第一个是设置组中的header,footer,还有children的点击事件,并且需要返回具体的索引,包括组索引,和组中孩子的索引。
    • 第二个是绑定viewHolder,主要作用是绑定数据到正确的Item视图上,这个可以把方法抽象,让子类去实现。
  • 封装后好处
    • 拓展性——每组支持添加header,footer,children,且每一个都支持设置多类型type的view视图。而且支持局部插入刷新,局部移除刷新,也就是说可以按组插入或者移除数据,或者按组中child的某个未知插入或者移除数据。
    • 可维护性——不同的列表类型由adapter添加header,footer,children类型处理,相互之间互不干扰,代码简洁,维护成本低。还可以灵活控制header,footer类型的布局是否可见,特别灵活!

参考案例说明

其他推荐说明

关于LICENSE

开源库地址:https://github.com/yangchong211/YCGroupAdapter

Adapter分组封装的更多相关文章

  1. Adapter的封装之路

    原文:Adapter的封装之路 一.几种常见列表效果: 假如要用RecyclerView实现下面的几种效果,你会如何实现呢? 效果1:单布局效果   效果2:多布局效果 有多种Item布局   效果3 ...

  2. android代码优化----ListView中自定义adapter的封装(ListView的模板写法)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  3. android RecycleView Adapter简单封装

    早些时候我们使用系统提供个的BaseAdapter的时候为了满足大家的需要,我们总会对BaseAdapter做一层上层的封装,然后对于实际业务我们只需要关心getView里面的View即可,是代码可读 ...

  4. 对adapter的封装优化

    一般不优化的adapter通常继承自BaseAdapter会出现一下几个问题: getCount(), getItem(), getItemId()代码都要去重写,一个adapter还行,如果adap ...

  5. RecyclerView下拉刷新上拉加载(三)—对Adapter的封装

    RecyclerView下拉刷新上拉加载(一) http://blog.csdn.net/baiyuliang2013/article/details/51506036 RecyclerView下拉刷 ...

  6. RecyclerView.Adapter封装,最简单实用的BaseRecyclerViewAdapter;只需重写一个方法,设置数据链式调用;

    之前对ListView的BaseAdapter进行过封装,只需重写一个getView方法: 现在慢慢的RecyclerView成为主流,下面是RecyclerView.Adapter的封装: Base ...

  7. 自己封装的工具类,使用原生SwipeRefreshLayout+RecycleView实现下拉刷新和加载更多

    实现SwipeRefreshLayout+RecycleView实现刷新 在你的xml文件里写上如下代码: <android.support.v4.widget.SwipeRefreshLayo ...

  8. Java 适配器(Adapter)模式

    一.什么是适配器模式: 把一个接口变成另外一个接口,使得原本因接口不匹配无法一起工作的两个类一起工作. 二.适配器模式的分类和结构: 适配器模式有类的适配器模式和对象的适配器模式两种. 1.类的适配器 ...

  9. 从头開始学 RecyclerView(三) 封装简化

    前言 上一篇的代码,也是基于这些封装的. RV的封装,跟曾经的listView之类的封装,大同小异. 这里,从@devwiki 处,将代码搬过来.基本无改动 BaseHolder的优化 使ViewHo ...

  10. (转载)Android快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup

    [置顶] [Android]快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup 标签: androidAdapter快速开发0耦合 2016-12-1 ...

随机推荐

  1. python-命令行参数处理 getopt模块详解

    背景 在写脚本程序的时候需要添加一些额外的参数来实现脚本的附加功能或者增强功能,通常的做法是通过sys.argv[i]直接来获取参数的值,但是这个比较局限,要求参数的输入一定要按照顺序. fileNa ...

  2. 使用SpeechRecognition进行语音识别

    操作系统 : CentOS7.7.1908_x64 gcc版本 :4.8.5 Python 版本 : 3.6.8 安装语音识别环境: virtualenv -p /usr/bin/python3 py ...

  3. SP9494 ZSUM - Just Add It 题解

    题目传送门 前置知识 快速幂 解法 推式子: \(\begin{aligned} Z_n+Z_{n-1}-2Z_{n-2}&=(Z_n-Z_{n-2})+(Z_{n-1}-Z_{n-2}) \ ...

  4. JS 数组中找到与目标值最接近的数字,记一次工作中关于二分查找的算法优化

    壹 ❀ 引 在最近的工作中,有一个任务是需要修复富文本编辑器字号显示的BUG.大概情况就是,从WPS中复制不同样式的标题.正文到到项目编辑器中,发现没办法设置选中的文本为正文:而且字体字号都显示为默认 ...

  5. 【XInput】游戏手柄模拟鼠标动作

    老周一般很少玩游戏,在某宝上买了一堆散件,计划在过年期间自己做个机械臂耍耍.头脑中划过一道紫蓝色的闪电,想起用游戏手柄来控制机械臂.机械臂是由树莓派(大草莓)负责控制,然后客户端通过 Socket U ...

  6. 【Unity3D】顶点和片元着色器

    1 前言 ​ 上文介绍了渲染管线.固定管线着色器和表面着色器,如下: 渲染管线 固定管线着色器一 固定管线着色器二 表面着色器 ​ 固定管线着色器通过命令方式实现光照和贴图等效果,表面着色器通过给 S ...

  7. 【C++ OOP 01】封装

    封装 封装的意义 封装是C++面向对象三大特性之一 封装的意义: 将属性和行为作为一个整体,表现生活中的事物 将属性和行为加以权限控制 封装意义一 ​ 在设计类的时候,属性和行为写在一起,表现事物 语 ...

  8. 以解析csv数据为例,讨论string、char[]、stream 不同类型来源是否能进行高性能读取解析封装可能性

    篇幅较长,所以首先列举结果,也就是我们的目的 核心目的为探索特定场景对不同类型数据进行统一抽象,并达到足够高性能,也就是一份代码实现,对不同类型数据依然高性能 以下为结果,也就是我们的目的: 对1w行 ...

  9. 从实测出发,掌握 NebulaGraph Exchange 性能最大化的秘密

    自从开发完 NebulaGraph Exchange,混迹在各个 NebulaGraph 微信群的我经常会看到一类提问是:NebulaGraph Exchange 的性能如何?哪些参数调整下可以有更好 ...

  10. C++特殊类的设计与单例模式

    #pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝, 只需让该类不能调用拷贝构造函数以及赋值运算 ...