感謝點進來看的各位技術(shù)小可愛窗声,本篇文章為純干貨,希望閱讀完本文的你能有所收獲彼妻,幫助大家提高項目的開發(fā)效率嫌佑。
閱讀本文你將收獲:
1豆茫、簡潔好用的萬能適配器一個
2、DataBinding的簡單使用
3屋摇、Kotlin和DataBinding結(jié)合使用遇到的問題
4揩魂、Github制作自己的在線Library
廢話不多說,先來直接看一下炮温,CommonAdaper結(jié)合DataBinding后火脉,咱們寫一個列表的Adapter代碼成本,僅僅只需要7行代碼柒啤。如下:
class ADA_ChapterFilter constructor(context: Context): CommonAdapter<DataBean, ItemLayoutBinding>(context) {
override fun convert(viewBinding: ItemLayoutBinding?, holder: ViewHolder.BindingHolder?, bean: DataBean?, position: Int) {
viewBinding!!.dataBean= bean
}
override fun itemLayoutId(): Int {
return R.layout.item_layout
}
}
是倦挂,你沒看沒錯,就是這么簡潔597皆!省去了一大堆數(shù)據(jù)裝載時的setText等冗余代碼涛癌。下面是使用它實現(xiàn)的列表效果:《一》本篇簡介
關(guān)于通用的適配器犯戏,相信大家也看過不少博客,如果還有在用傳統(tǒng)的方式寫列表適配器的新手拳话,那要趕快跟緊步伐啦先匪,因為你可能已經(jīng)落后不是一點點了哦。當然弃衍,其實即使是要自己去手寫一套萬能Adapter呀非,也并不是很困難的事情爽篷,所以大家不需要畏懼洞拨,其實核心思想就是代碼的封裝和抽象茅茂,以及一些設(shè)計模式的運用辽聊,感興趣的可以自己動手試試。本篇文章的基礎(chǔ)闻妓,是鴻洋大神的BaseAdapter岁钓,支持ListView和RecyclerView的Adapter狸捅,且能支持多類型列表的適配 激涤,能很好的滿足日常項目開發(fā)的需求。本篇文章就是在他寫的BaseAdapter的基礎(chǔ)上判呕,進行了改造倦踢,所以下面開始介紹經(jīng)我簡單改造后的DataBindingCommonAdapter。
《二》使用方法
(1)在你的工程根目錄下添加:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
(2)在你的app的build.gradle下添加依賴
dependencies {
implementation 'com.github.GraceJoJo:DataBindingBaseAdapter:1.0.1'
}
(3)RecyclerView中Adapter的用法:
class ADA_RecyclerItem constructor(context: Context): CommonAdapter<DataBean, ItemLayoutBinding>(context) {
override fun convert(viewBinding: ItemLayoutBinding?, holder: ViewHolder.BindingHolder?, bean: DataBean?, position: Int) {
viewBinding!!.dataBean = bean
}
override fun itemLayoutId(): Int {
return R.layout.item_layout
}
}
Activity或Fragment使用:
val dataList= ArrayList<DataBean>() //模擬數(shù)據(jù)
recyclerview.layoutManager = LinearLayoutManager(this)
var mAdapter = ADA_RecyclerItem(this)
recyclerview.adapter = mAdapter
mAdapter.update(dataList,true)
(4)ListView或者GridView的Adapter的用法:
class ADA_ListItem constructor(context: Context): CommonAdapterListView<DataBean, ItemLayoutBinding>(context) {
override fun convert(viewBinding: ItemLayoutBinding?, holder: ViewHolderListView?, bean: DataBean?, position: Int) {
viewBinding!!.dataBean = bean
}
override fun itemLayoutId(): Int {
return R.layout.item_layout
}
}
Activity或Fragment使用:
val dataList= ArrayList<DataBean>() //模擬數(shù)據(jù)
var mAdapter = ADA_ListItem(this)
listview.adapter = mAdapter
mAdapter.update(dataList,true)
《三》對BaseAdapter的改造思路
我們來看看晤碘,BaseAdapter未改造前褂微,RecyclerView的Adapter寫法可能是這樣的:不了解鴻洋大神的萬能適配方案的侠草,可以點擊:BaseAdapter先學習了解一下辱挥,也可以直接下載文末我改造后的案例。本篇文章著重講解RecyclerView的Adapter的改造边涕,完整的源碼請去文末下載哦~
其實相比原始的寫法還是很簡單的,但是如果涉及的字段比較多园爷,那么就會有大量的setText()等宠蚂,雖然BaseAdapter已經(jīng)很大程度上簡化了Adapter,但是我們還是每次都要寫很多重復(fù)的簡單代碼童社。
分析:歸根結(jié)底求厕,其實寫Adapter無非就是下面幾個要素
(1)寫一個item布局文件
(2)告訴Adapter每個item對應(yīng)的bean是什么
(3)綁定數(shù)據(jù):給item布局中的控件設(shè)置對應(yīng)的數(shù)據(jù)
①item布局,不管你如何簡化扰楼,都得寫上呀癣,這個毋庸置疑;
②可以看到未改造前的BaseAdapter弦赖,已經(jīng)將第二點bean類以泛型的形式抽離出來了项栏;
③那么我們看看第三點,是不是可以對它做點什么蹬竖。借鑒著把bean類抽離一個泛型的思想沼沈,結(jié)合DataBinding,每個item布局文件會對應(yīng)一個ViewDataBinding案腺,所以我把ViewDataBinding抽離出一個泛型出來庆冕。
1、在CommonAdapter中抽離出ViewDataBinding的泛型:
2劈榨、在ViewHolder中使用DataBinding綁定布局:
3访递、在onBindViewHolder中把布局對應(yīng)的某一個具體的ViewBinding傳出去,供數(shù)據(jù)更新時給控件設(shè)置數(shù)據(jù)使用:
4同辣、改造后的使用:
class ADA_RecyclerItem constructor(context: Context): CommonAdapter<DataBean, ItemLayoutBinding>(context) {
override fun convert(viewBinding: ItemLayoutBinding?, holder: ViewHolder.BindingHolder?, bean: DataBean?, position: Int) {
viewBinding!!.dataBean = bean
}
override fun itemLayoutId(): Int {
return R.layout.item_layout
}
}
總結(jié):
通過簡單的改造拷姿,我們寫Adapter時,就只需要給Adapter一個布局旱函、一個具體的bean响巢、一個布局文件對應(yīng)的具體的ViewDataBinding,然后在布局文件中使用DataBinding把數(shù)據(jù)綁定寫好棒妨,一個Adapter的工作就完成了踪古。
結(jié)合了DataBinding后,我們將數(shù)據(jù)與頁面的綁定券腔,在寫布局的時候就把頁面控件對應(yīng)的數(shù)據(jù)綁定了伏穆,這樣省去了大量的BindView操作和對view設(shè)置數(shù)據(jù)的處理。
《四》DataBinding的簡單介紹——MVVM
DataBinding不知道大家熟悉與否纷纫,不管怎樣枕扫,我都要在這里隆重的介紹一下它,因為讓代碼如此簡潔的大功臣辱魁,正是DataBinding烟瞧。
(1)DataBinding是什么诗鸭?
① DataBinding是一個support library,所以它可以支持所有的android sdk,最低可以到android2.1(API7)参滴。
② 使用DataBinding需要Android Gradle插件的支持强岸,版本至少在1.5以上,需要的Android studio的版本在1.3以上卵洗。
(2)首先请唱,我們在需要用到DataBinding的module或者library的build.gradle中,使其支持DataBinding过蹂。android{ }下添加如下代碼:
// 打開Data Binding , 這樣我們可以通過聲明式布局以精簡的代碼來綁定應(yīng)用程序邏輯和布局
dataBinding{
enabled = true
}
(3)XML布局中做聲明數(shù)據(jù)綁定
例如:以本例Adapter對于的item_layout的布局為例十绑,寫法如下:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@android:color/white">
<!--data節(jié)點下一個variable節(jié)點代表一個變量,
name屬性根據(jù)需要自己取名酷勺,type為需要用到的Model的全路徑本橙,
功能相當于寫代碼的時候引入一個類的功能-->
<data>
<variable
name="dataBean"
type="com.example.jojo.databinding_commonadapter.DataBean"></variable>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:paddingRight="15dp">
<FrameLayout
android:id="@+id/ll_rank"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true">
<TextView
android:id="@+id/tv_rank_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_marginRight="5dp"
android:textColor="#2E3439"
android:textSize="12sp"
android:textStyle="bold" />
</FrameLayout>
<ImageView
android:id="@+id/iv_cover"
android:layout_width="60dp"
android:layout_height="80dp"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:layout_toRightOf="@+id/ll_rank"
android:padding="1px"
android:scaleType="fitXY"
app:imageUrl="@{bean.covor_url}" />
<LinearLayout
android:id="@+id/ll_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="12dp"
android:layout_toRightOf="@+id/iv_cover"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginBottom="7dp"
android:includeFontPadding="false"
android:text="@{bean.name_cn}"
android:textColor="#2E3439"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginBottom="6dp"
android:text="@{bean.author}"
android:textColor="#666666"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginBottom="11dp"
android:ellipsize="end"
android:inputType="textMultiLine"
android:lines="2"
android:text="@{bean.comment}"
android:textColor="#999999"
android:textSize="10sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/ll_info"
android:layout_marginTop="10dp"
android:background="#f9f9f9"></View>
</RelativeLayout>
</layout>
(3)定義數(shù)據(jù)綁定的Data對象:
data class DataBean constructor(val name_cn: String, val comment: String, val author: String, val covor_url: String)
(4)使用DataBindingUtil,綁定布局與數(shù)據(jù)脆诉。
Android studio會根據(jù)layout文件自動生成一個默認的Binding類甚亭,類名是根據(jù)layout文件名生成的,并有"Binding"后綴結(jié)束击胜。
情景1:在Activity中
MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
User user = new User("Test", "User");
binding.setUser(user); //數(shù)據(jù)更新亏狰,設(shè)置給綁定的控件,此時即完成了頁面的數(shù)據(jù)刷新
情景2:在Fragment中
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// Inflate the layout for this fragment
FragmentLayoutBinding viewBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_layout, container, false);
return viewDataBinding.getRoot();
}
關(guān)于DataBinding偶摔,更多詳細的介紹及一些高級用法暇唾,我就不在本文多加贅述了
《五》遇到的問題及解決
(1)如果不熟悉DataBinding的朋友可能會有疑問。如果是加載圖片或者是某個控件綁定的數(shù)據(jù)展示需要特殊處理咋辦辰斋?這就是DataBinding的知識了策州,這里我簡單說一下這種情況的處理方法。
DataBinding有個BindingAdapter宫仗,它的功能是用來設(shè)置view的屬性值够挂。
假設(shè)你要在布局中顯示一個圓角圖片,咋辦藕夫?你可以新建一個類孽糖,叫ViewBindingAdapter。
public class ViewBindingAdapter {
@BindingAdapter({"app:imageUrl"})
public static void loadImage(ImageView imageView, String url) {
RequestOptions requestOptions = new RequestOptions()
.priority(Priority.HIGH)
.transform(new CircleCrop());
Glide.with(MyApplication.context)
.load(url)
.apply(requestOptions)
.transition(new DrawableTransitionOptions().crossFade())
.into(imageView);
}
@BindingAdapter({"app:date_text"})
public static void setDateText(TextView tv, String text) {
//處理文本顯示
tv.setText(text + "年");
}
}
布局文件中引用:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@android:color/white">
<!--data節(jié)點下一個variable節(jié)點代表一個變量毅贮,
name屬性根據(jù)需要自己取名梭姓,type為需要用到的Model的全路徑,
功能相當于寫代碼的時候引入一個類的功能-->
<data>
<variable
name="dataBean"
type="com.example.jojo.databinding.DataBean"></variable>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_cover"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:imageUrl="@{dataBean.covor_url}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:date_text="@{dataBean.time}"
android:textSize="14sp" />
</RelativeLayout>
</layout>
像這樣嫩码,你可以在ViewBindingAdapter里創(chuàng)建多個@BindingAdapter注解的方法,來特殊處理你在布局文件要給控件綁定的數(shù)據(jù)值罪既。
(2)Kotlin下使用DataBinding遇到的問題
dataBinding+kotlin環(huán)境下會報錯:Error: Unresolved reference: databinding
解決:在app的build.gradle下添加铸题,sync now即可恢復(fù)正常铡恕。
我的app的Android plugin版本為 classpath 'com.android.tools.build:gradle:3.0.1'
dependencies {
kapt 'com.android.databinding:compiler:3.0.1'
}
kapt {
generateStubs = true
}
寫在結(jié)尾:
對本文有問題的朋友歡迎大家留言交流哦~
(1)本文完整Demo請戳github地址
(2)感謝鴻洋大神的BaseAdapter
(3)GitHub上制作自己的Library,直接compile使用
最后丢间,附上我的一個Kotlin編寫+組件化開發(fā)的開源項目Designer
Kotlin+組件化開發(fā)實踐—開源項目Designer-App
Designer項目算是傾注了我蠻多心血了探熔,每個頁面和功能都當成是上線的App來做,App的logo還特地做了UI設(shè)計??力求做到精致和完善烘挫,其中還包括了很多自己項目開發(fā)中的經(jīng)驗匯總和對新技術(shù)的探索和整合诀艰,希望對各位讀者有所幫助,歡迎點個star饮六,follow其垄,或者給個小心心,嘻嘻??也可以分享給你更多的朋友一起學習卤橄,您的支持是我不斷前進的動力绿满。如果有任何問題,歡迎在GitHub上給我提issue或者留言窟扑。