美文网首页Android技术知识程序员Android开发
DataBinding:一行实现花式列表

DataBinding:一行实现花式列表

作者: 木木00 | 来源:发表于2017-03-20 10:31 被阅读362次

作者简介 原创微信公众号郭霖 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()即可:

淘宝链接: 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

相关文章

网友评论

    本文标题:DataBinding:一行实现花式列表

    本文链接:https://www.haomeiwen.com/subject/jfybnttx.html