Android Databinding技術(shù)由淺入深(2)------Databinding的簡單使用

本文參照Data Binding Library - Android Developers 谷歌官方


這篇文章主要講述我自己使用過程中遇到的一些問題和自己的理解,后面也列出許多知識(shí)點(diǎn)。

先介紹一下使用這個(gè)功能我們需要改變的一些思維:

1.layout變化:起始根標(biāo)簽是layout,接下來一個(gè)data元素以及一個(gè)view的根元素。layout是在原來布局的基礎(chǔ)上包了一層。

2.起始根標(biāo)簽是layout的布局Android Studio會(huì)生成一個(gè)類,類名可以指定。

3.layout中用的語法為POJO。

Databinding的知識(shí)點(diǎn)我感覺比較多,但好多我感覺不必細(xì)看,粗略看一下就可以,用的頻率最多的就那么幾個(gè),在實(shí)際使用中會(huì)感受到。


1)兼容性配置

你可以在所有的Android平臺(tái)最低能到Android 2.1(API等級(jí)7+)上使用它。

需求:Android Plugin for Gradle1.5.0-alpha1更高版本。

2)Android Studio內(nèi)配置構(gòu)建環(huán)境

要開始使用Data Binding,首先需要在Android SDK Manager的支持庫里下載該庫。

你的app要使用Data Binding,需要添加Data Binding到gradle構(gòu)建文件里,如下:

android{? ? ....? ? dataBinding {enabled=true}? ? }

Data Binding插件將會(huì)在你的項(xiàng)目內(nèi)添加必需提供的以及編譯配置依賴。

3)Data Binding Layout文件

a)Data Binding表達(dá)式

Data Binding layout文件有點(diǎn)不同的是:起始根標(biāo)簽是layout,接下來一個(gè)data元素以及一個(gè)view的根元素。這個(gè)view元素就是你沒有使用Data Binding的layout文件的根元素。舉例說明如下:

data內(nèi)描述了一個(gè)名為user的變量屬性,使其可以在這個(gè)layout中使用:

在layout的屬性表達(dá)式寫作@{},下面是一個(gè)TextView的text設(shè)置為user的firstName屬性:

b)Data對(duì)象

假設(shè)你有一個(gè)user的plain-old Java Object(POJO):

publicclassUser{publicfinalStringfirstName;publicfinalStringlastName;publicUser(StringfirstName,StringlastName) {this.firstName = firstName;this.lastName = lastName;? }}

這個(gè)類型的對(duì)象擁有從不改變的數(shù)據(jù)。在app中它是常見的,可以讀取一次并且之后從不改變。當(dāng)然也可以使用JavaBeans對(duì)象:

publicclassUser{privatefinalString firstName;privatefinalString lastName;publicUser(String firstName, String lastName) {this.firstName = firstName;this.lastName = lastName;? }publicString getFirstName() {returnthis.firstName;? }publicString getLastName() {returnthis.lastName;? }}

從Data Binding的角度來看,這兩個(gè)類是等價(jià)的。用于TextView中的android:text屬性的表達(dá)式@{user.firstName}將訪問前者POJO對(duì)象中的firstName和后者JavaBeans對(duì)象中的getFirstName()方法。

c)Binding數(shù)據(jù)

默認(rèn)情況下,一個(gè)Binding類會(huì)基于layout文件的名稱而產(chǎn)生,將其轉(zhuǎn)換為Pascal case(譯注:首字母大寫的命名規(guī)范)并且添加“Binding”后綴。上述的layout文件是main_activity.xml,因此生成的類名是MainActivityBinding。此類包含從layout屬性到layout的Views中所有的bindings(例如user變量),并且它還知道如何給Binding表達(dá)式分配數(shù)值。創(chuàng)建bindings的最簡單的方式是在inflating(譯注:layout文件與Activity/Fragment的“鏈接”)期間如下:

@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);? MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);? User user =newUser("Test","User");? binding.setUser(user);}

就是這樣,運(yùn)行app后,你將會(huì)看到Test User?;蛘吣憧梢酝ㄟ^如下獲取View:

MainActivityBinding binding= MainActivityBinding.inflate(getLayoutInflater());

如果你在ListView或者RecyclerViewadapter使用Data Binding時(shí),你可能會(huì)使用:

ListItemBindingbinding= ListItemBinding.inflate(layoutInflater, viewGroup,false);//orListItemBindingbinding= DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup,false);

d)事件處理

數(shù)據(jù)綁定允許你編寫表達(dá)式來處理view分派的事件。事件屬性名字取決于監(jiān)聽器方法名字。例如View.OnLongClickListeneronLongClick()的方法,因此這個(gè)事件的屬性是android:onLongClick。處理事件有兩種方法:

Method References

Listener Bindings

4)深入Layout文件

a)Import

零個(gè)或多個(gè)import元素可能在data元素中使用。這些只用在你的layout文件中添加引用,就像在Java中:

現(xiàn)在,View可以使用你的Binding表達(dá)式:

當(dāng)類名有沖突時(shí),其中一個(gè)類名可以重命名為alias::

這樣,在該layout文件中Vista對(duì)應(yīng)com.example.real.estate.View,而View對(duì)應(yīng)android.view.View。導(dǎo)入的類型可以在Variable和表達(dá)式中使用作為引用來使用:

? ? ? ? ? ? ? ? "/>

注意:Android Studio還沒有處理imports,所以自動(dòng)導(dǎo)入Variable在你的IDE不能使用。您的app仍會(huì)正常編譯,你可以在您的Variable定義中使用完全符合規(guī)定的名稱來解決該IDE問題。

導(dǎo)入的類型還可以在表達(dá)式中使用static屬性和方法:

就像在Java中,java.lang。*是自動(dòng)導(dǎo)入的。

b)Variables

在data中可以使用任意數(shù)量的variable元素。每一個(gè)variable元素描述了一個(gè)用于layout文件中Binding表達(dá)式的屬性。


該Variable類型在編譯時(shí)檢查,因此如果一個(gè)Variable實(shí)現(xiàn)了Observableobservable collection,這應(yīng)該反映在類型中。(譯注:需要查找資料來理解)如果variable是一個(gè)沒有實(shí)現(xiàn)Observable接口的基本類或者接口,Variables不會(huì)被observed!

當(dāng)對(duì)于多種配置有不同的layout文件時(shí)(如,橫向或縱向),Variables會(huì)被合并。這些layout文件之間必須不能有沖突的Variable定義。

產(chǎn)生的Binding類對(duì)于每一個(gè)描述的Variables都會(huì)有setter和getter。這些Variables會(huì)使用默認(rèn)的Java值 - null(引用類型)、0(int)、false(boolean)等等,直到調(diào)用setter時(shí)。

c)自定義Binding類名稱

默認(rèn)情況下,Binding類的命名是基于所述layout文件的名稱,用大寫開頭,除去下劃線()以及()后的第一個(gè)字母大寫,然后添加“Binding”后綴。這個(gè)類將被放置在一個(gè)模塊封裝包里的databinding封裝包下。例如,所述layout文件contact_item.xml將生成ContactItemBinding。如果模塊包是com.example.my.app,那么它將被放置在com.example.my.app.databinding。

Binding類可通過調(diào)整data元素中的class屬性來重命名或放置在不同的包中。例如:

...

在模塊封裝包的databinding包中會(huì)生成名為ContactItem的Binding類。如果要想讓該類生成在不同的包種,你需要添加前綴.,如下:

...

在這個(gè)情況下,ContactItem類直接在模塊包種生成?;蛘吣憧梢蕴峁┱麄€(gè)包名:

...

d)Includes

通過使用application namespace以及在屬性中的Variable名字從容器layout中傳遞Variables到一個(gè)被包含的layout:

注意:在name.xml以及contact.xml兩個(gè)layout文件中必需要有uservariable

e)表達(dá)式

常用表達(dá)式跟Java表達(dá)式很像,以下這些是一樣的:

數(shù)學(xué)+-/*%

字符串連接+

邏輯&&||

二進(jìn)制&|^

一元運(yùn)算+-!~

移位>>>>><<

比較==><>=<=

instanceof

分組()

null

Cast

方法調(diào)用

數(shù)據(jù)訪問[]

三元運(yùn)算?:

示例:

android:text="@{String.valueOf(index + 1)}"android:visibility="@{age < 13 ? View.GONE : View.VISIBLE}"android:transitionName='@{"image_" + id}'

缺少的操作:

this

super

new

顯式泛型調(diào)用

Null合并操作

??- 左邊的對(duì)象如果它不是null,選擇左邊的對(duì)象;或者如果它是null,選擇右邊的對(duì)象:

android:text="@{user.displayName ?? user.lastName}"

函數(shù)上的寫法如下:

android:text="@{user.displayName!=null?user.displayName:user.lastName}"

屬性引用

第一個(gè)已經(jīng)在前邊提到了a)Data Binding表達(dá)式:JavaBean引用的簡短格式。

當(dāng)一個(gè)表達(dá)式引用一個(gè)類的屬性,它仍使用同樣的格式對(duì)于字段、getters以及ObservableFields。

android:text="@{user.lastName}"

避免 NullPointerException

Data Binding代碼生成時(shí)自動(dòng)檢查是否為nulls來避免出現(xiàn)null pointer exceptions錯(cuò)誤。例如,在表達(dá)式@{user.name}中,如果user是null,user.name會(huì)賦予它的默認(rèn)值(null)。如果你引用user.age,age是int類型,那么它的默認(rèn)值是0

集合

常用的集合:arrays、lists、sparse lists以及maps,為了簡便都可以使用[]來訪問。

? ? ? ? ">? ">? ">? ? …android:text="@{list[index]}"…android:text="@{sparse[index]}"…android:text="@{map[key]}"

字符串

當(dāng)使用單引號(hào)包含屬性值時(shí),在表達(dá)式中使用雙引號(hào)很容易:

android:text='@{map["firstName"]}'

使用雙引號(hào)來包含屬性值也是可以的。字符串前后需要使用"`":

android:text="@{map[`firstName`]}"android:text="@{map["firstName"]}"

Resources

使用正常的表達(dá)式來訪問resources也是可行的:

android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"

格式化字符串和復(fù)數(shù)可以通過提供參數(shù)來判斷

android:text="@{@string/nameFormat(firstName, lastName)}"android:text="@{@plurals/banana(bananaCount)}"

當(dāng)復(fù)數(shù)需要多個(gè)參數(shù)時(shí),所有的參數(shù)都會(huì)通過:

Have an orangeHave %d orangesandroid:text="@{@plurals/orange(orangeCount, orangeCount)}"

一些資源需要顯式類型判斷:

類型正常引用表達(dá)式引用

String[]@array@stringArray

int[]@array@intArray

TypedArray@array@typedArray

Animator@animator@animator

StateListAnimator@animator@stateListAnimator

color int@color@color

ColorStateList@color@colorStateList

5)Data 對(duì)象

任何Plain old Java object(PO??JO)可用于Data Binding,但修改POJO不會(huì)導(dǎo)致UI更新。Data Binding的真正能力是當(dāng)數(shù)據(jù)變化時(shí),可以通知給你的Data對(duì)象。有三種不同的數(shù)據(jù)變化通知機(jī)制:Observable對(duì)象、ObservableFields以及observable? collections。

當(dāng)這些可觀察Data對(duì)象??綁定到UI,Data對(duì)象屬性的更改后,UI也將自動(dòng)更新。

a)Observable 對(duì)象

實(shí)現(xiàn)android.databinding.Observable接口的類可以允許附加一個(gè)監(jiān)聽器到Bound對(duì)象以便監(jiān)聽對(duì)象上的所有屬性的變化。

Observable接口有一個(gè)機(jī)制來添加和刪除監(jiān)聽器,但通知與否由開發(fā)人員管理。為了使開發(fā)更容易,一個(gè)BaseObservable的基類為實(shí)現(xiàn)監(jiān)聽器注冊(cè)機(jī)制而創(chuàng)建。Data實(shí)現(xiàn)類依然負(fù)責(zé)通知當(dāng)屬性改變時(shí)。這是通過指定一個(gè)Bindable注解給getter以及setter內(nèi)通知來完成的。

privatestaticclassUserextendsBaseObservable{privateString firstName;privateString lastName;@BindablepublicStringgetFirstName(){returnthis.firstName;? }@BindablepublicStringgetFirstName(){returnthis.lastName;? }publicvoidsetFirstName(String firstName){this.firstName = firstName;? ? ? notifyPropertyChanged(BR.firstName);? }publicvoidsetLastName(String lastName){this.lastName = lastName;? ? ? notifyPropertyChanged(BR.lastName);? }}

在編譯期間,Bindable注解在BR類文件中生成一個(gè)Entry。BR類文件會(huì)在模塊包內(nèi)生成。如果用于Data類的基類不能改變,Observable接口通過方便的PropertyChangeRegistry來實(shí)現(xiàn)用于儲(chǔ)存和有效地通知監(jiān)聽器。

b)Observable 字段

一些小工作會(huì)涉及到創(chuàng)建Observable類,因此那些想要節(jié)省時(shí)間或者幾乎沒有幾個(gè)屬性的開發(fā)者可以使用ObservableFields。ObservableFields是自包含具有單個(gè)字段的observable對(duì)象。它有所有基本類型和一個(gè)是引用類型。要使用它需要在data對(duì)象中創(chuàng)建public final字段:

privatestaticclassUser{publicfinal ObservableField firstName =newObservableField<>();publicfinal ObservableField lastName =newObservableField<>();publicfinal ObservableInt age =newObservableInt();}

就是這樣,要訪問該值,使用set和get方法:

user.firstName.set("Google");int age = user.age.get();

c)Observable 集合

一些app使用更多的動(dòng)態(tài)結(jié)構(gòu)來保存數(shù)據(jù)。Observable集合允許鍵控訪問這些data對(duì)象。ObservableArrayMap用于鍵是引用類型,如String。

ObservableArrayMapuser= new ObservableArrayMap<>();user.put("firstName","Google");user.put("lastName","Inc.");user.put("age", 17);

在layout文件中,通過String鍵可以訪問map:

"/>…

ObservableArrayList用于鍵是整數(shù):

ObservableArrayListuser= new ObservableArrayList<>();user.add("Google");user.add("Inc.");user.add(17);

在layout文件中,通過索引可以訪問list:

"/>…

6)Binding生成

Binding類的生成鏈接了layout中variables與Views。如前面所討論的,Binding的名稱和包名可以定制。所生成的Binding類都擴(kuò)展了android.databinding.ViewDataBinding。

a)創(chuàng)建

Binding應(yīng)在inflation之后就立馬創(chuàng)建,以確保View層次結(jié)構(gòu)不在之前打擾layout中的binding到views上的表達(dá)式。有幾個(gè)方法可以綁定到一個(gè)layout。最常見的是在Binding類上使用靜態(tài)方法.inflate方法載入View的層次結(jié)構(gòu)并且綁定到它只需這一步。還有一個(gè)更簡單的版本,只需要LayoutInflater還有一個(gè)是采用ViewGroup:

MyLayoutBinding binding= MyLayoutBinding.inflate(layoutInflater);MyLayoutBinding binding= MyLayoutBinding.inflate(LayoutInflater, viewGroup, false);

如果使用不同的機(jī)制載入layout,他可一分開綁定:

MyLayoutBinding binding= MyLayoutBinding.bind(viewRoot);

有時(shí)Binding不能提前知道,對(duì)于這種情況,可以使用DataBindingUtil類來創(chuàng)建Binding:

ViewDataBindingbinding= DataBindingUtil.inflate(LayoutInflater, layoutId,? ? parent, attachToParent);ViewDataBindingbinding= DataBindingUtil.bindTo(viewRoot,layoutId);

b)帶ID的Views

在layout中對(duì)于每個(gè)帶ID的View會(huì)生成一個(gè)public final字段。Binding在View層次結(jié)構(gòu)上做單一的傳遞,提取帶ID的Views。這種機(jī)制比起某些Views使用findViewById還要快。例如:

它會(huì)生成如下的Binding類:

publicfinalTextView firstName;publicfinalTextView lastName;

IDs不像沒有Data Bindings那樣幾乎沒有必要,但是仍然會(huì)有一些實(shí)例需要從代碼中訪問Views。

c)Variables

每個(gè)Variable會(huì)有訪問方法。


它會(huì)在Binding中生成setters和getters:

publicabstractcom.example.UsergetUser();publicabstractvoidsetUser(com.example.User user);publicabstractDrawablegetImage();publicabstractvoidsetImage(Drawable image);publicabstractStringgetNote();publicabstractvoidsetNote(String note);

d)ViewStubs

ViewStubs跟正常的Views略有不同。他們開始時(shí)是不可見的,當(dāng)他們要么設(shè)置為可見或被明確告知要載入時(shí),它們通過載入另外一個(gè)layout取代了自己。

由于ViewStub基本上從View的層次結(jié)構(gòu)上消失,在Binding對(duì)象的View也必須消失來允許被收集。因?yàn)閂iews是最后的,一個(gè)ViewStubProxy對(duì)象取帶ViewStub,給開發(fā)者獲得了ViewStub,當(dāng)它存在以及還可以訪問載入的View層次結(jié)構(gòu)時(shí)當(dāng)ViewStub已被載入時(shí)。

當(dāng)載入另一個(gè)layout,為新的布局必需創(chuàng)建一個(gè)Binding。因此,ViewStubProxy必需監(jiān)聽ViewStub的OnInflateListener監(jiān)聽器并在那個(gè)時(shí)候建立Binding。因?yàn)橹挥幸粋€(gè)可以存在,ViewStubProxy允許開發(fā)者在其上設(shè)置一個(gè)OnInflateListener它會(huì)在建立Binding后調(diào)用。

e)Binding進(jìn)階

動(dòng)態(tài)Variables

有時(shí),不知道具體的Binding類,例如,一個(gè)RecyclerView適配器對(duì)layouts任意操作并不知道具體的Binding類。它仍然必需在onBindViewHolder期間賦值給Binding。

在這個(gè)例子中,該RecyclerView綁定的所有l(wèi)ayouts有一個(gè)“item”的Variable。該BindingHolder有一個(gè)getBinding方法返回ViewDataBinding。

publicvoidonBindViewHolder(BindingHolder holder,intposition) {? final T item = mItems.get(position);? holder.getBinding().setVariable(BR.item, item);? holder.getBinding().executePendingBindings();}

直接Binding

當(dāng)一個(gè)variable或observable變化時(shí),binding會(huì)在下一幀之前被計(jì)劃要改變。有很多次,但是在Binding時(shí)必須立即執(zhí)行。要強(qiáng)制執(zhí)行,使用executePendingBindings()方法。

后臺(tái)線程

只要它不是一個(gè)集合,你可以在后臺(tái)線程中改變你的數(shù)據(jù)模型。在判斷是否要避免任何并發(fā)問題時(shí),Data Binding會(huì)對(duì)每個(gè)Varialbe/field本地化。

7)屬性Setters

每當(dāng)綁定值的變化,生成的Binding類必須調(diào)用setter方法??。Data Binding框架有可以自定義賦值的方法。

a)自動(dòng)Setters

對(duì)于一個(gè)屬性,Data Binding試圖找到setAttribute方法。與該屬性的namespace并不什么關(guān)系,僅僅與屬性本身名稱有關(guān)。

例如,有關(guān)TextView的android:text屬性的表達(dá)式會(huì)尋找一個(gè)setText(String)的方法。如果表達(dá)式返回一個(gè)int,Data Binding會(huì)搜索的setText(int)方法。注意:要表達(dá)式返回正確的類型,如果需要的話使用casting。Data Binding仍會(huì)工作即使沒有給定名稱的屬性存在。然后,您可以通過Data Binding輕松地為任何setter“創(chuàng)造”屬性。例如,DrawerLayout沒有任何屬性,但大量的setters。您可以使用自動(dòng)setters來使用其中的一個(gè)。

b)重命名的Setters

一些有setters的屬性按名稱并不匹配。對(duì)于這些方法,屬性可以通過BindingMethods注解相關(guān)聯(lián)。這必須與一個(gè)包含BindingMethod注解的類相關(guān)聯(lián),每一個(gè)用于一個(gè)重命名的方法。例如,android:tint屬性與setImageTintList相關(guān)聯(lián),而不與setTint相關(guān)。

@BindingMethods({@BindingMethod(type ="android.widget.ImageView",? ? ? ? ? ? ? ? ? ? ? attribute ="android:tint",? ? ? ? ? ? ? ? ? ? ? method ="setImageTintList"),})

以上例子,開發(fā)者需要重命名setters是不太可能了,android架構(gòu)屬性已經(jīng)實(shí)現(xiàn)了。

c)自定義Setters

有些屬性需要自定義綁定邏輯。例如,對(duì)于android:paddingLeft屬性并沒有相關(guān)setter。相反,setPadding(left, top, right, bottom)是存在在。一個(gè)帶有BindingAdapter注解的靜態(tài)綁定適配器方法允許開發(fā)者自定義setter如何對(duì)于一個(gè)屬性的調(diào)用。

Android的屬性已經(jīng)創(chuàng)造了BindingAdapters。舉例來說,對(duì)于paddingLeft:

@BindingAdapter("android:paddingLeft")publicstaticvoidsetPaddingLeft(View view,intpadding){? view.setPadding(padding,? ? ? ? ? ? ? ? ? view.getPaddingTop(),? ? ? ? ? ? ? ? ? view.getPaddingRight(),? ? ? ? ? ? ? ? ? view.getPaddingBottom());}

Binding適配器對(duì)其他定制類型非常有用。例如,自定義loader可以用來異步載入圖像。

當(dāng)有沖突時(shí),開發(fā)人員創(chuàng)建的Binding適配器將覆蓋Data Binding默認(rèn)適配器。

您也可以創(chuàng)建可以接收多個(gè)參數(shù)的適配器。

@BindingAdapter({"bind:imageUrl","bind:error"})publicstaticvoidloadImage(ImageView view, String url, Drawableerror){? Picasso.with(view.getContext()).load(url).error(error).into(view);}

如果對(duì)于一個(gè)ImageViewimageUrlerror都被使用并且imageUrl是一個(gè)string類型以及error是一個(gè)drawable時(shí),該適配器會(huì)被調(diào)用。

匹配的過程中自定義namespaces將被忽略。

你也可以為Android namespaces寫適配器。

8)轉(zhuǎn)換

a)對(duì)象轉(zhuǎn)換

當(dāng)從Binding表達(dá)式返回一個(gè)對(duì)象,一個(gè)setter會(huì)從自動(dòng)、重命名以及自定義的setters中選擇。該對(duì)象將被轉(zhuǎn)換為所選擇的setter的參數(shù)類型。

這是為了方便那些使用ObservableMaps來保存數(shù)據(jù)。例如:

在userMap返回一個(gè)對(duì)象并且該對(duì)象將自動(dòng)轉(zhuǎn)換為setText(CharSequence)的參數(shù)類型。當(dāng)有關(guān)參數(shù)類型可能混亂時(shí),開發(fā)人員需要在表達(dá)式中轉(zhuǎn)換。

b)自定義轉(zhuǎn)換

有時(shí)候轉(zhuǎn)換應(yīng)該是自動(dòng)的在特定類型之間。例如,設(shè)置背景的時(shí)候:

這里,背景需要Drawable對(duì)象,但顏色是一個(gè)整數(shù)。不管何時(shí)有Drawable并且返回值是一個(gè)整數(shù),那么整數(shù)類型會(huì)被轉(zhuǎn)換為ColorDrawable。這個(gè)轉(zhuǎn)換是通過使用帶有BindingConversion注解的靜態(tài)方法完成的:

@BindingConversionpublicstaticColorDrawableconvertColorToDrawable(intcolor){returnnewColorDrawable(color);}

注意:轉(zhuǎn)換僅僅發(fā)生在setter級(jí)別,因此它是不允許以下混合類型:

9)Android Studio支持

Android Studio為數(shù)據(jù)綁定支持許多的代碼編輯。例如,它支持以下功能:

語法高亮

標(biāo)記表達(dá)式的語法錯(cuò)誤

XML代碼補(bǔ)全

引用,包括navigation(如導(dǎo)航到聲明處)以及快速文檔查詢

注意: 數(shù)組以及通用類型,比如說Observable類,可能會(huì)顯示錯(cuò)誤事實(shí)上并沒有錯(cuò)誤。


做技術(shù)的,不要畏首畏尾,要樂于嘗試新的技術(shù)。

學(xué)習(xí)目錄

1.Android Databinding技術(shù)由淺入深(1)------Databinding的介紹

2.Android Databinding技術(shù)由淺入深(2)------Databinding的簡單使用

3.Android Databinding技術(shù)由淺入深(3)------Databinding的源碼解析

4.Android Databinding技術(shù)由淺入深(4)------Databinding進(jìn)階MVVM全框架

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,179評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,628評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,444評(píng)論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,948評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,185評(píng)論 0 287
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,717評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,602評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,794評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,045評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評(píng)論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,414評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,750評(píng)論 2 370

推薦閱讀更多精彩內(nèi)容