DataBinding:一行實現(xiàn)花式列表

作者簡介 原創(chuàng)微信公眾號郭霖 WeChat ID: guolin_blog

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

本篇來自老司機張旭童投稿,繼續(xù)給大家?guī)砹嗽瓌?chuàng)的開源庫。本文是此開源庫系列的第二篇(主要涉及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

現(xiàn)在V1.2.0版本發(fā)布,我又加入了我最近超愛的一個技術(shù),DataBinding。

封裝了一套一行代碼實現(xiàn)花式列表的Adapter。即利用 DataBinding 實現(xiàn) RecyclerView 中快速使用的 Adapter。

以后不管寫多種type還是單type的列表,利用?DataBinding?和?本庫,都只需要一行代碼!

這里也算是安利 DataBinding 吧,真的超好用。還沒使用的朋友們,在看到本文可以如此簡單寫花式列表后,建議去學習一下。先看用法吧,簡單粗暴到?jīng)]朋友。

用法

使用必讀

BaseBindingAdapter?利用 DataBinding 提供的動態(tài)綁定技術(shù),使用?BR.data?封裝數(shù)據(jù)、BR.itemP?封裝點擊事件。所以對?layout 有以下要求:

layout中 數(shù)據(jù)name 起名data

layout中 點擊事件Presenter 起名 itemP

比如:

1. 單Item列表

效果如圖,順帶演示了 BaseBindingAdapter 封裝的一些增刪功能:


用法:

和其他 BaseAdapter 用法一致

構(gòu)造函數(shù)只需要傳入 context,datas,layout

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

好了,列表已經(jīng)出來了。我不騙你,就這一句話。如果需要設(shè)置點擊事件(點擊事件設(shè)置所有類型都一樣,下不贅述):

特殊需求:如果有特殊需求,可傳入兩個泛型,重寫onBindViewHolder搞事情:

2. 多Item同種數(shù)據(jù)類型列表

一般是像IM那種列表,雖然Item不同,但是數(shù)據(jù)結(jié)構(gòu)是同一個。用法,一句話~效果如圖:


用法:

數(shù)據(jù)結(jié)構(gòu)(JavaBean)需實現(xiàn)?IBaseMulInterface接口,根據(jù)情況返回不同的layout。

構(gòu)造函數(shù)只需要傳入context,datas.

mAdapter=newBaseMulTypeBindingAdapter(this, mDatas);

復(fù)雜列表依然一句話:

特殊需求:如果有特殊需求,可傳入數(shù)據(jù)結(jié)構(gòu)的泛型,避免強轉(zhuǎn),重寫?onBindViewHolder()?方法,但是 Binding類 不可避免的需要強轉(zhuǎn)了:

3. 多Item、多種數(shù)據(jù)類型列表

各大APP首頁,Banner、列表、推薦混排,數(shù)據(jù)結(jié)構(gòu)肯定不同,但是依然只要一句代碼搞定Adapter!效果如圖:


用法:

數(shù)據(jù)結(jié)構(gòu)(JavaBean)需分別實現(xiàn)?IBaseMulInterface接口,返回數(shù)據(jù)結(jié)構(gòu)對應(yīng)的layout。

構(gòu)造函數(shù)只需要傳入context,datas.

mAdapter=newBaseMulTypeBindingAdapter(this, mDatas);

特殊需求:如果有特殊需求,重寫?onBindViewHolder()方法,但是 數(shù)據(jù)結(jié)構(gòu) 和 Binding類 都不可避免的需要強轉(zhuǎn)了:

4. 不能忘了上文的ViewGroup

上文封裝的 ViewGroup 類型 Adapter 也提供 DataBinding 的支持。當然還是流式布局搭配我自己的側(cè)滑菜單控件。效果如圖:


用法:上文一樣,只是 Adapter 換成?SingleBindingAdapter

如果需要設(shè)置點擊事件:

mAdapter.setItemPresenter(newItemDelPresenter());

設(shè)計思路與實現(xiàn)

使用起來如此爽快,其實寫起來也很簡單。

注意 類BaseBindingAdapter?和?BaseMulTypeBindingAdapter?都不是?abstract?的,這說明我們不需要重寫任何方法

利用 DataBinding,我們在 BasexxxAdapter內(nèi)部 和 xml 分別做View的創(chuàng)建和數(shù)據(jù)綁定的工作。

UML類圖

先簡要概括:

BaseBindingVH?繼承自?RecyclerView.ViewHolder,持有?T extends ViewDataBinding類型的?mBinding?變量。利用?ViewDataBinding?我們將不用再寫任何?ViewHolder。

BaseBindingAdapter,繼承自?RecyclerView.Adapter,依賴?BaseBindingVH,onCreateViewHolder(ViewGroup parent, int viewType)方法 返回?BaseBindingVH?作為?ViewHolder。

內(nèi)部持有三個重要變量:數(shù)據(jù)對應(yīng)layout,數(shù)據(jù)集,Item點擊事件處理類。數(shù)據(jù)對應(yīng)layout 會在?onCreateViewHolder(ViewGroup parent, int viewType)?用到。剩下兩個變量在?onBindViewHolder()?用到。對外暴漏?setItemPresenter(Object itemPresenter)供設(shè)置點擊事件處理類。

IBaseMulInterface接口 和上文提到的一樣,返回某個數(shù)據(jù)結(jié)構(gòu)對應(yīng)的layout,除此之外,本文還有一個十分tricky之處,利用返回的?R.layout.itemxxxx?作為?ItemViewType,在?BaseMulTypeBindingAdapter?會用到。

BaseMulTypeBindingAdapter?繼承自?BaseBindingAdapter,但是它不再關(guān)心?mLayoutId?變量,它利用?IBaseMulInterface接口 返回的?R.layout.itemxxxx?作為?ItemViewType,這樣在?onCreateViewHolder(ViewGroup parent, int viewType)?的時候,就可以直接用?viewType?構(gòu)造出?ItemView。不再依賴?mLayoutId?變量。這是一個我很得意的設(shè)計,我在"優(yōu)雅為RecyclerView增加HeaderView"一文中,也曾用過這個方法。

BaseBindingVH

BaseBindingVH?算是一個核心類,但是又十分簡單。它繼承自?RecyclerView.ViewHolder,持有由泛型傳入的?T extends ViewDataBinding?類型的mBinding變量。

唯一構(gòu)造函數(shù),需要一個?T t?變量,然后調(diào)用?super()?傳入?t.getRoot()?完成?itemView?的賦值。同時對?mBinding?變量賦值。對外暴漏?getBinding()?返回?mBinding?變量。

利用?ViewDataBinding?我們將不用再寫任何?ViewHolder。

BaseBindingAdapter

BaseBindingAdapter,繼承自?RecyclerView.Adapter,依賴?BaseBindingVH,將?BaseBindingVH?作為泛型傳給?RecyclerView.Adapter。

同時?BaseBindingAdapter?本身接受兩個泛型,。

泛型沒有特殊需求可以不傳

泛型D:是Bean類型,如果有就傳。

泛型B:是對應(yīng)的xml Layout的Binding類

傳入不傳入泛型的區(qū)別已經(jīng)在第二節(jié)具體用法里進行了演示,不再贅述。內(nèi)部持有三個重要變量:

數(shù)據(jù)對應(yīng)layout?int mLayoutId;

數(shù)據(jù)集?List mDatas;

Item點擊事件處理類。Object ItemPresenter;

mLayoutId?和?mDatas?都由構(gòu)造函數(shù)傳入,沒啥好說的。

對外暴漏?setItemPresenter(Object itemPresenter)?供設(shè)置點擊事件處理類?ItemPresenter。ItemPresenter?是?Object?類型,這樣才不care你set的Item點擊事件處理類是什么鬼。

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

mLayoutId?會在?onCreateViewHolder(ViewGroup parent, int viewType)?用到,再根據(jù)泛型B強轉(zhuǎn)成對應(yīng)的?ViewDataBinding:

會在?onBindViewHolder()?方法里,利用 DataBinding 動態(tài)綁定?ViewDataBinding.setVariable(BR.itemP, ItemPresenter);為每個Item設(shè)置點擊事件。

同時,數(shù)據(jù)也是同樣在里面綁定的:setVariable(BR.data, mDatas.get(position))。重點代碼如下:

BaseBindingAdapter 內(nèi)部也封裝了如下方法,方便數(shù)據(jù)刷新,增刪(定向刷新)調(diào)用:

IBaseMulInterface接口

IBaseMulInterface接口 和上文提到的一樣,返回某個數(shù)據(jù)結(jié)構(gòu)對應(yīng)的layout.

除此之外,本文還有一個十分tricky之處,利用返回的?R.layout.itemxxxx?作為?ItemViewType,在?BaseMulTypeBindingAdapter?會用到。因為不同的?R.layout.itemxxxx?對于 RecyclerView 來說一定是不同的Item。

BaseMulTypeBindingAdapter

多種ItemType的Base類

BaseMulTypeBindingAdapter?繼承自?BaseBindingAdapter,但是它不再關(guān)心?mLayoutId?變量。因此它傳給父類的 泛型B 就是?ViewDataBinding類 本身。解釋如下:

基類的泛型B:不用傳,因為多種 ItemType 肯定 Layout 長得不一樣,那么 Binding類 也不一樣,傳入沒有任何意義

泛型T:多Item 多Bean 情況可以不傳。如果只有一種Bean類型,可以傳入Bean,實現(xiàn) IBaseMulInterface接口?;蛘邆魅?IBaseMulInterface接口,可以拿到 ?getItemLayoutId(),但是通過 getItemViewType(int position) 一樣。所以多Item多Bean建議不傳。傳入不傳入泛型的區(qū)別已經(jīng)在第二節(jié)具體用法里進行了演示,不再贅述。

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

在?onCreateViewHolder(ViewGroup parent, int viewType)?的時候,直接用?viewType?構(gòu)建?ViewDataBinding(ItemView)。不再依賴?mLayoutId?變量。

完整代碼如下:

ViewGroup Adapter的實現(xiàn)

單item

繼承 SingleAdapter,增加 ItemPresenter,在 getView() 完成View創(chuàng)建和綁定。

多Item

更簡單了,繼承 SingleBindingAdapter。重寫getView()即可:

總結(jié)

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

利用?Object類型 的?ItemPresenter,兼容解決了點擊事件的設(shè)置。

最得意的設(shè)計,還是利用?R.layout.xxxx?這些布局文件?int類型 的 RID,作為?ItemViewType,一箭雙雕。

DataBinding?很強,希望大家快點擁抱它。

to do list

ViewGroup Adapter 考慮加入復(fù)用緩存池

ViewGroup Adapter ,考慮替換onBindView()的ItemView->通用的ViewHolder,這樣可以少寫一些findViewById()代碼

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

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

加入一些自定義ViewGroup入庫,例如流式布局,九宮格,Banner輪播圖。


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

文章原創(chuàng)作者GuoLin 書籍推薦

郭林大神原創(chuàng)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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容