DataBinding:一行实现花式列表

作者简介 原创微信公众号郭霖 WeChat ID: guolin_blog

大家周五好,提前祝大家周末愉快!

本篇来自老司机张旭童投稿,继续给大家带来了原创的开源库。本文是此开源库系列的第二篇(主要涉及DataBinding),所以文中的上文指系列的第一篇,想从头了解的朋友可以访问他的博客查看。

张旭童的博客地址:

http://blog.csdn.net/zxt0601

前言

中,我们利用 Adapter模式 封装了一个库,能快速为 任意ViewGroup 添加 子View。有如下特点:

快速简单使用

支持任意ViewGroup

无耦合

无侵入性

Item支持多种类型

在库中V1.1.0版本,我也顺手加入了 RecyclerView、ListView、GridView 的通用 Adapter 功能,库地址:

https://github.com/mcxtzhang/all-base-adapter

现在V1.2.0版本发布,我又加入了我最近超爱的一个技术,DataBinding

封装了一套一行代码实现花式列表的Adapter。即利用 DataBinding 实现 RecyclerView 中快速使用的 Adapter。

以后不管写多种type还是单type的列表,利用 DataBinding 和 本库,都只需要一行代码!

这里也算是安利 DataBinding 吧,真的超好用。还没使用的朋友们,在看到本文可以如此简单写花式列表后,建议去学习一下。先看用法吧,简单粗暴到没朋友。

用法

使用必读

BaseBindingAdapter 利用 DataBinding 提供的动态绑定技术,使用 BR.data 封装数据、BR.itemP 封装点击事件。所以对 layout 有以下要求:

layout中 数据name 起名data

layout中 点击事件Presenter 起名 itemP

比如:

1. 单Item列表

效果如图,顺带演示了 BaseBindingAdapter 封装的一些增删功能:


用法:

和其他 BaseAdapter 用法一致

构造函数只需要传入 context,datas,layout

mAdapter=newBaseBindingAdapter(this, mDatas,R.layout.item_db_single);

好了,列表已经出来了。我不骗你,就这一句话。如果需要设置点击事件(点击事件设置所有类型都一样,下不赘述):

特殊需求:如果有特殊需求,可传入两个泛型,重写onBindViewHolder搞事情:

2. 多Item同种数据类型列表

一般是像IM那种列表,虽然Item不同,但是数据结构是同一个。用法,一句话~效果如图:


用法:

数据结构(JavaBean)需实现 IBaseMulInterface接口,根据情况返回不同的layout。

构造函数只需要传入context,datas.

mAdapter=newBaseMulTypeBindingAdapter(this, mDatas);

复杂列表依然一句话:

特殊需求:如果有特殊需求,可传入数据结构的泛型,避免强转,重写 onBindViewHolder() 方法,但是 Binding类 不可避免的需要强转了:

3. 多Item、多种数据类型列表

各大APP首页,Banner、列表、推荐混排,数据结构肯定不同,但是依然只要一句代码搞定Adapter!效果如图:


用法:

数据结构(JavaBean)需分别实现 IBaseMulInterface接口,返回数据结构对应的layout。

构造函数只需要传入context,datas.

mAdapter=newBaseMulTypeBindingAdapter(this, mDatas);

特殊需求:如果有特殊需求,重写 onBindViewHolder()方法,但是 数据结构 和 Binding类 都不可避免的需要强转了:

4. 不能忘了上文的ViewGroup

上文封装的 ViewGroup 类型 Adapter 也提供 DataBinding 的支持。当然还是流式布局搭配我自己的侧滑菜单控件。效果如图:


用法:上文一样,只是 Adapter 换成 SingleBindingAdapter

如果需要设置点击事件:

mAdapter.setItemPresenter(newItemDelPresenter());

设计思路与实现

使用起来如此爽快,其实写起来也很简单。

注意 类BaseBindingAdapter 和 BaseMulTypeBindingAdapter 都不是 abstract 的,这说明我们不需要重写任何方法

利用 DataBinding,我们在 BasexxxAdapter内部 和 xml 分别做View的创建和数据绑定的工作。

UML类图

先简要概括:

BaseBindingVH 继承自 RecyclerView.ViewHolder,持有 T extends ViewDataBinding类型的 mBinding 变量。利用 ViewDataBinding 我们将不用再写任何 ViewHolder。

BaseBindingAdapter,继承自 RecyclerView.Adapter,依赖 BaseBindingVH,onCreateViewHolder(ViewGroup parent, int viewType)方法 返回 BaseBindingVH 作为 ViewHolder。

内部持有三个重要变量:数据对应layout,数据集,Item点击事件处理类。数据对应layout 会在 onCreateViewHolder(ViewGroup parent, int viewType) 用到。剩下两个变量在 onBindViewHolder() 用到。对外暴漏 setItemPresenter(Object itemPresenter)供设置点击事件处理类。

IBaseMulInterface接口 和上文提到的一样,返回某个数据结构对应的layout,除此之外,本文还有一个十分tricky之处,利用返回的 R.layout.itemxxxx 作为 ItemViewType,在 BaseMulTypeBindingAdapter 会用到。

BaseMulTypeBindingAdapter 继承自 BaseBindingAdapter,但是它不再关心 mLayoutId 变量,它利用 IBaseMulInterface接口 返回的 R.layout.itemxxxx 作为 ItemViewType,这样在 onCreateViewHolder(ViewGroup parent, int viewType) 的时候,就可以直接用 viewType 构造出 ItemView。不再依赖 mLayoutId 变量。这是一个我很得意的设计,我在"优雅为RecyclerView增加HeaderView"一文中,也曾用过这个方法。

BaseBindingVH

BaseBindingVH 算是一个核心类,但是又十分简单。它继承自 RecyclerView.ViewHolder,持有由泛型传入的 T extends ViewDataBinding 类型的mBinding变量。

唯一构造函数,需要一个 T t 变量,然后调用 super() 传入 t.getRoot() 完成 itemView 的赋值。同时对 mBinding 变量赋值。对外暴漏 getBinding() 返回 mBinding 变量。

利用 ViewDataBinding 我们将不用再写任何 ViewHolder。

BaseBindingAdapter

BaseBindingAdapter,继承自 RecyclerView.Adapter,依赖 BaseBindingVH,将 BaseBindingVH 作为泛型传给 RecyclerView.Adapter。

同时 BaseBindingAdapter 本身接受两个泛型,。

泛型没有特殊需求可以不传

泛型D:是Bean类型,如果有就传。

泛型B:是对应的xml Layout的Binding类

传入不传入泛型的区别已经在第二节具体用法里进行了演示,不再赘述。内部持有三个重要变量:

数据对应layout int mLayoutId;

数据集 List mDatas;

Item点击事件处理类。Object ItemPresenter;

mLayoutId 和 mDatas 都由构造函数传入,没啥好说的。

对外暴漏 setItemPresenter(Object itemPresenter) 供设置点击事件处理类 ItemPresenter。ItemPresenter 是 Object 类型,这样才不care你set的Item点击事件处理类是什么鬼。

onCreateViewHolder(ViewGroup parent, int viewType) 方法返回 BaseBindingVH 作为 ViewHolder。

mLayoutId 会在 onCreateViewHolder(ViewGroup parent, int viewType) 用到,再根据泛型B强转成对应的 ViewDataBinding:

会在 onBindViewHolder() 方法里,利用 DataBinding 动态绑定 ViewDataBinding.setVariable(BR.itemP, ItemPresenter);为每个Item设置点击事件。

同时,数据也是同样在里面绑定的:setVariable(BR.data, mDatas.get(position))。重点代码如下:

BaseBindingAdapter 内部也封装了如下方法,方便数据刷新,增删(定向刷新)调用:

IBaseMulInterface接口

IBaseMulInterface接口 和上文提到的一样,返回某个数据结构对应的layout.

除此之外,本文还有一个十分tricky之处,利用返回的 R.layout.itemxxxx 作为 ItemViewType,在 BaseMulTypeBindingAdapter 会用到。因为不同的 R.layout.itemxxxx 对于 RecyclerView 来说一定是不同的Item。

BaseMulTypeBindingAdapter

多种ItemType的Base类

BaseMulTypeBindingAdapter 继承自 BaseBindingAdapter,但是它不再关心 mLayoutId 变量。因此它传给父类的 泛型B 就是 ViewDataBinding类 本身。解释如下:

基类的泛型B:不用传,因为多种 ItemType 肯定 Layout 长得不一样,那么 Binding类 也不一样,传入没有任何意义

泛型T:多Item 多Bean 情况可以不传。如果只有一种Bean类型,可以传入Bean,实现 IBaseMulInterface接口。或者传入 IBaseMulInterface接口,可以拿到  getItemLayoutId(),但是通过 getItemViewType(int position) 一样。所以多Item多Bean建议不传。传入不传入泛型的区别已经在第二节具体用法里进行了演示,不再赘述。

getItemViewType() 直接返回 IBaseMulInterface接口 的返回值。

在 onCreateViewHolder(ViewGroup parent, int viewType) 的时候,直接用 viewType 构建 ViewDataBinding(ItemView)。不再依赖 mLayoutId 变量。

完整代码如下:

ViewGroup Adapter的实现

单item

继承 SingleAdapter,增加 ItemPresenter,在 getView() 完成View创建和绑定。

多Item

更简单了,继承 SingleBindingAdapter。重写getView()即可:

总结

本文利用 DataBinding 的 ViewDataBinding 直接略去写 ViewHolder。

利用 Object类型 的 ItemPresenter,兼容解决了点击事件的设置。

最得意的设计,还是利用 R.layout.xxxx 这些布局文件 int类型 的 RID,作为 ItemViewType,一箭双雕。

DataBinding 很强,希望大家快点拥抱它。

to do list

ViewGroup Adapter 考虑加入复用缓存池

ViewGroup Adapter ,考虑替换onBindView()的ItemView->通用的ViewHolder,这样可以少写一些findViewById()代码

整合 DataBinding 的通用Adapter入库。(已完成)

完善 RecyclerView、ListView的通用Adapter,支持多种ItemViewType。

加入一些自定义ViewGroup入库,例如流式布局,九宫格,Banner轮播图。


完。。。。。。。。。。。。。。。。。。。。。

文章原创作者GuoLin 书籍推荐

郭林大神原创android 书籍:《第一行代码 android》

淘宝链接: https://s.click.taobao.com/t?e=m%3D2%26s%3DgKUfuKdAZKocQipKwQzePOeEDrYVVa64K7Vc7tFgwiHjf2vlNIV67p2n%2BQBNMyE6Rku8%2Bpj6eJall3bs%2B3NRhNHnsKI%2BqxhyM0iVZhTFBom4YIorMPnmg8G0g2OJi%2FzmXHfenomYtn5EW9vzeG8LzfPUwktUBEmkxg5p7bh%2BFbQ%3D&pvid=10_106.6.161.154_3367_1490163222155

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容