Adapter的封装之路
原文:Adapter的封装之路
一、几种常见列表效果:
假如要用RecyclerView实现下面的几种效果,你会如何实现呢?
效果1:单布局效果
效果2:多布局效果
有多种Item布局
效果3:多布局多列效果
有多种Item布局,有的Item占1行,有的Item占1/2行
二、使用方法
1.原始的Adapter-单布局效果
在最原始的用法中,我们需要自己去继承RecyclerView.Adapter,然后写一大坨形式化的代码:
然后在Activity中调用这个Adapter,感觉很麻烦有木有?
实现效果如图1。
2.封装后的单布局的Adapter
看!再也不用自己去继承RecyclerView.Adapter,写那么一大坨了,轻轻松松几行代码搞定
实现效果如图1。
3.升级后的多布局的Adapter
使用多布局的Adapter时候呢,我需要实现两个方法了,一个绑定布局,一个用来绑定数据,不过也不算麻烦,比起那些写个多布局写的欲仙欲死的原始写法而言,我们已经很幸福了,不算么?
实现效果如图2。
4.再次升级,多布局-多实体的Adapter
简单的多布局呢,就像聊天界面的发送和接受一样,只是布局不一样,但是布局所使用的数据源其实是一致的,就像3里面一样,都是SimpleBean
但是,还有很多坑爹的多布局呢,不只是布局不一样,连数据源也不一样,如果要:
R.layout.item_super对应SuperBean,
R.layout.item_simple对应SimpleBean,
你会怎么搞?
下面看我的用法!用LayoutWrapper<T>包起来,不就统一成一种实体了么?
为了让不同的布局绑定数据之间尽量解耦,我加了一个新的DataHolder,来专门处理布局--数据的映射关系。
实现效果如图2。
6.究极进化!多布局-多实体-多列的Adapter
我们已经实现了多布局中,每个布局都可以对应一个实体了,但是,这就够了么?no! too native!
要知道,产品的想法、UI的创意,是我们这些凡人永远无法预料的?
你能猜到下一版又会改成什么风格么?额,扯远了,先把上面的效果3实现了再说吧,毕竟,这种效果也是非常非常常见的,也是让很多人觉得头疼的,尤其是,当我们要实现这种效果:
注意哦!里面的车型、车龄、里程等分组项是后台配的,至于每个分组里面的选择项,就更是不用说了。
当一切都是动态可配置的时候,你该何去何从?还敢用线性布局嵌套多个列表来硬编码么?
其实我们发现这个黑不溜秋的界面,其实也就是上面的效果3的升级版,所以,我们只要能实现效果3就可以了。
下面亮大招!
其实RecyclerView的LayoutManager是可以控制每个Item所占的列数的,所以,我们可以在包装类LayoutWrapper里面,再加一个表示列数的字段即可!
使用时,主要注意两点:
- GridLayoutManager的列数,应该是所有Item的列数的最小公倍数!比如我有两种Item,分别为一行显示1个和2个,于是最小公倍数是2
- LayoutWrapper的表示列数的字段,则是最小公倍数/N,N表示一行显示多少个,比如一行显示1个,则为2,一行显示2个,则为1
实现效果如图3。搞定收工!
其实,你的所有界面,除去导航栏和底部工具栏,中间全部可以用RecyclerView来实现!
每个item表示一块区域,这样分区域的来实现,也是一种很好的解耦思路,避免改了下面的视图,上面的视图莫名其妙的被改了。
三.具体的封装过程:
我想分享的,不仅仅只是工具类,更是封装的思想!
当然,也许我的封装有不妥之处,欢迎和我探讨!@QQ:630709658
1、SingleAdapter:将Adapter从具体到泛型
思路:
- 构造时传入layoutId
- 数据类型泛化
- 提取出万能的SuperViewHolder
- bindData的方法抽象化,延迟实现(交由具体的子类实现)
这里还用到了一个封装的万能ViewHolder
2-MultiAdapter:从单布局到多布局
思路:
- 构造时传入layoutId数组
- 添加layoutMap,记录layoutId--viewType的对应关系
- bindLayout的方法抽象化,由子类实现Item--layoutId的对应关系
这里主要有以下两部分:用map存放viewType和layoutId的对应关系
用map.entrySet来根据value读取key
3-SuperAdapter:多布局中,从单实体到多实体
思路:
- 将泛型T升级为包装类LayoutWrapper,持有布局id,泛型数据Item,控制器holder
- 提取出接口DataHolder,用于实现ViewHolder和ItemData的绑定
这里主要是:
1、定义了布局包装类
2、定义了控制器接口
3、由控制器接口的bind来负责绑定
4-LayoutWrapper:多布局中,配置某项可占据多列
思路:
- LayoutWrapper添加spanSize属性,记录该item的列数
- 使用时调用gridLayoutManager.setSpanSizeLookup来动态设置列数
然后使用时:
- 如果你的代码中,存在着大段相同或极其相似的代码,那么,开始重构吧!
- 在不断的重构中,你会发现:实现很重要,如何组织这些实现也同样重要!
- 重构两个着力点:数据泛型化、方法抽象化
最后和大家分享一句话:
封装技术的快速提升,来自于对代码的不断重构
当然,没有单元测试作为保障的重构,谁也不敢说自己就不会在重构中:自己把自己给作死了!so,要重构,更要单测!不说了,我继续研究单元测试了,不得不说,Android这个坑货,单元测试还真麻烦,凡是用到了Android系统的API的地方,一律不能用JUnit测试(在不引入Roboletric的情况下)因为:
IDE和SDK只为Android开发者提供了开发和编译一个项目的环境,并没有提供运行这个项目的环境!
开发时使用的android.jar里面的class实现是不完整的,它们只是一些stub,如果你打开android.jar下面的代码去看看,你会发现所有的方法都只有一行实现:throw RuntimeException("stub!!”);
而运行unit test,说白了还是个运行的过程,所以如果你的unit test代码里面有android相关的代码的话,那运行的时候将会抛出RuntimeException("stub!!”)。
额,不小心扯远了。先别说了,把工具类奉上:
所有代码均已上传到:Github,欢迎Star!
原文链接:http://www.jianshu.com/p/f530318be47a#
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
Adapter的封装之路的更多相关文章
- android代码优化----ListView中自定义adapter的封装(ListView的模板写法)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- android RecycleView Adapter简单封装
早些时候我们使用系统提供个的BaseAdapter的时候为了满足大家的需要,我们总会对BaseAdapter做一层上层的封装,然后对于实际业务我们只需要关心getView里面的View即可,是代码可读 ...
- 对adapter的封装优化
一般不优化的adapter通常继承自BaseAdapter会出现一下几个问题: getCount(), getItem(), getItemId()代码都要去重写,一个adapter还行,如果adap ...
- RecyclerView下拉刷新上拉加载(三)—对Adapter的封装
RecyclerView下拉刷新上拉加载(一) http://blog.csdn.net/baiyuliang2013/article/details/51506036 RecyclerView下拉刷 ...
- ibatis集成封装之路(to mysql)
hello <tx:annotation-driven transaction-manager=" "/> 插入记录ID的坑 https://renjieguixion ...
- RecyclerView让列表嵌套如此简单
平常开发时,相信像这样的页面,大家一定是遇到过的.这里比较坑爹的地方在于呢:列表嵌套.订单列表中的每一项,都包含一个商品列表.像这种需求,大家会如何实现呢? 这里呢,说一下我自己的思路,我没有使用列表 ...
- RecyclerView.Adapter封装,最简单实用的BaseRecyclerViewAdapter;只需重写一个方法,设置数据链式调用;
之前对ListView的BaseAdapter进行过封装,只需重写一个getView方法: 现在慢慢的RecyclerView成为主流,下面是RecyclerView.Adapter的封装: Base ...
- 自己封装的工具类,使用原生SwipeRefreshLayout+RecycleView实现下拉刷新和加载更多
实现SwipeRefreshLayout+RecycleView实现刷新 在你的xml文件里写上如下代码: <android.support.v4.widget.SwipeRefreshLayo ...
- Java 适配器(Adapter)模式
一.什么是适配器模式: 把一个接口变成另外一个接口,使得原本因接口不匹配无法一起工作的两个类一起工作. 二.适配器模式的分类和结构: 适配器模式有类的适配器模式和对象的适配器模式两种. 1.类的适配器 ...
随机推荐
- 实用控件分享:自定义逼真相机光圈View
最近手机界开始流行双摄像头,大光圈功能也应用而生.所谓大光圈功能就是能够对照片进行后期重新对焦,其实现的原理主要是对拍照期间获取的深度图片与对焦无穷远的图像通过算法来实现重新对焦的效果. 在某双摄手机 ...
- Android--split()分割字符串特殊用法
split()分割字符串 1.不同环境下的区分 Java:分割字符串不能写成split("$")//$为要分割的字符Android:分割字符串需要加上中括号split(" ...
- JavaScript Array和string的转换
Array类可以如下定义: var aValues = new Array(); 如果预先知道数组的长度,可以用参数传递长度 var aValues = new Array(20); -------- ...
- Xamarin For Visual Studio 3.0.54.0 完整离线破解版(C# 开发Android、IOS工具 吾乐吧软件站分享)
Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xamarin For iOS,最新版的已经把两个独立的插件合并为一个exe安装包了.为了区分 ...
- 归档—监控ORACLE数据库告警日志
ORACLE的告警日志里面包含许多有用的信息,尤其是一些ORACLE的ORA错误信息,所以有必要及时归档.监控数据库告警日志的ORA错误,及时提醒数据库管理员DBA处理这些错误信息,那么我们首先来看看 ...
- 解决MyEclipse中的js报错的小方法
今天,下了个模版,但是导进去的时候发现js会报错.看了下其他都没有错误.而有一个js报错误,请原谅我有点红色强迫症,不能留一点红色 . 错误如下:Syntax error on token " ...
- wordpress-4.4.1 数据库表结构解析
wordpress-4.4.1.zip 安装包 SQL结构 : wp_commentmeta :文章评论额外信息表. CREATE TABLE IF NOT EXISTS `wp_commentm ...
- 你不一定懂的cpu显示信息
在linux命令中用top查看系统的情况,在cpu这一行有一些分部表示什么 下面有一篇博文,对此写的非常清楚,特转载.猛击下面的链接 http://www.cnblogs.com/yjf512/p/3 ...
- 打地鼠游戏iOS源码项目
打地鼠游戏源码,游戏是一款多关卡基于cocos2d的iPad打地鼠游戏源码,这也是一款高质量的打地鼠游戏源码,可以拥有逐步上升的关卡的设置,大家可以在关卡时设置一些商业化的模式来盈利的,非常完美的一款 ...
- Java 容器(list, set, map)
java容器类库的简化图: (虚线框表示接口, 实线框表示普通的类, 空心箭头表示特定的类实现了接口, 实心箭头表示某个类可以生成箭头所指的类对象) 继承Collection的主要有Set 和 Lis ...