轉摘:https://www.zybuluo.com/shark0017/note/256112
DBinding權威使用指南
零、使用方式
layout:

Activity:

一、設計思路
1.1 三層結構
我們的項目結構里經常會出現(xiàn)這三種東西————M/V/C,這三個東西一定要廣義理解為層,他們絕對不是狹義的類對象(因為有些語言中會有view、controller、model這樣的類,請不要混淆)。所謂各種模式其實就是這三者的不同組合和通信方式。

要說明白這個問題,就要知道哪些是v,哪些是m,哪些是c。
V:視圖層
v層是可以獨立數(shù)據(jù)而顯示的,它里面沒有什么業(yè)務邏輯,僅僅是做展現(xiàn)。簡單比喻來看就是一個提線木偶,它本身并不會有生命。Android中的view,比如textview,button,自定義的view當然也屬于此類。
除了上述這些類對象外,activity、fragment算不算v層的東西呢?
如果看前面的定義,他們貌似都處于灰色地帶,很難得到明確的定義。不過我們可以進行思維方式的轉換,人為定義它們的意義。相比起傳統(tǒng)的思路,我反而認為activity和fragment是屬于v層的,activity可以做視圖的綁定操作,并且可以在activity中方便的寫視圖的動畫和布局切換效果。如果把activity變成別的層,那么你就很難找到一個適合的類去做這些事情了。
M:邏輯層
用于封裝業(yè)務邏輯相關的數(shù)據(jù)以及對數(shù)據(jù)的處理方法。M本身是完全獨立的個體,并且應該能被監(jiān)聽到執(zhí)行的結果。M不應該知道view的存在。m層最直觀的例子就是網絡請求,網絡請求是完全獨立于視圖層的,而且做的事情也是很單一,可以很好的被復用。
C:控制層
用來控制數(shù)據(jù)、處理view和數(shù)據(jù)的交互,它主要接收來自view的交互信號和數(shù)據(jù)層的改變結果,然后做相應的操作。早期的c層是鍵盤和鼠標,所以是可以直接面向用戶進行操作的,但是在移動時代它慢慢變成了一個純的控制對象。
如果說c層是用來做控制的,adapter算不算c呢?
adapter的意義大家都心知肚明,是用來做數(shù)據(jù)和view的綁定工作的,順便更新下ui。如果說數(shù)據(jù)是血液,view是皮囊,那么adapter就是一個賦予view生命的輸血機器。它本該屬于的層最初我是很難把控的,我嘗試過把它放入c層,也嘗試過把它放入activity這樣的view層,但都沒能得到很好的答案。
最終,在commonAdapter這個項目的啟發(fā)下,明白了adapter最合適的位置應該是c層。因為adapter中會做很多數(shù)據(jù)的處理,比如根據(jù)數(shù)據(jù)類型選擇item這樣的操作。而這樣的操作如果放入view層,就會讓view層一下子失去復用的能力,因此adapter放入c層是最合適的選擇。
順便說一句,c層是最不容易被復用的。因此如果一個東西是和當前頁面獨有的,不可能被復用的。那么它就應該死在c里,不要把它放出來。
1.2 MVC

我剛接觸android的時候就聽過android是MVC模式的,以為android的view層可以理解為layout(xml)層。但之后發(fā)現(xiàn)很多項目中竟會在自定義view中處理了很多業(yè)務邏輯,而且activity經常被用來做了view和controller的事情,慢慢的android項目就
成了下面這樣:

分析
在這段代碼中我們認為xml文件就是view層,activity做view和model的綁定操作,看起來activity又像c又像v。而且,在這種情況下activity會越來越臃腫,即便有fragment的加入,也無濟于事。這種糟糕的情況就是android設計之初對activity定義不明的一個惡果。
我先拋幾個問題:
1. activity該做view的綁定工作么?
2. activity要做view的動畫操作么?
3. activity應處理從網絡返回的結果么?
4. activity需要做不同狀態(tài)下view的狀態(tài)的控制么?
我相信大家都有了答案吧。為了解決activity臃腫和含義不清的矛盾,慢慢出現(xiàn)了mvp規(guī)范。
1.3 MVP

mvp做的事情也相當簡單,僅僅是把mvc做了一個小小的改造,產生了清晰的封層。
【流程】view操作p,p會去調用model執(zhí)行操作,p中接收到結果后去調用v來更新界面。
下面是某個使用mvp的項目中activity的代碼:

這種方式將activity和xml文件變成了一個v,那么所有邏輯都交由p處理。這樣的好處就是model對外層不知情,p對view不知情。成為了這樣的一個蛋形結構:

內層對外層不知情的好處就是內層可以隨意地做復用,壞處就是需要建立相互通信的機制,會帶來各種回調。當然,你可以用Rx的方式很簡單地做回調,但是我們是否真的應該采用這種到處拋出回調的方式呢?
先別急,我們先看看如果上面的例子變復雜的情況:
我希望點擊按鈕后,出現(xiàn)一個loading界面,p去做網絡請求。無論成功與否,請求回來后都停止loading。如果成功得到了網絡數(shù)據(jù),才更新頁面。

可以看出mvp中一個很蛋疼的后遺癥————各種回調。而且這些回調都是要自己根據(jù)不同頁面寫的,而且每寫一個回調就要寫一個接口,接口的參數(shù)也要根據(jù)需求變。我敢保證絕對沒辦法一次性知道這個回調方法需要幾個參數(shù),而參數(shù)的類型也不能一次性就確定。
我覺得太麻煩了,我要簡單一些。比如讓P對v知曉,v也知道p的存在,會不會簡單?趕快來看看這種方案是什么樣的。
首先讓activity實現(xiàn)某個接口比如IAppInfoUi,然后讓P調用這個接口對象進行交互。
Activity:

Presenter:

現(xiàn)在,p和v的交互也不用各種回調了(將activity整體變成了一個回調接口)。那,這種方式有不會有什么問題?
p知道了v,那么p的復用性就喪失了。正如你所見,我利用接口來降低了二者互相知情造成的影響。但這樣,你就必須在寫view的時候定義接口,但如果你這個頁面根本沒復用價值,你還要做接口么。如果不做接口,你怎么知道這個頁面真的沒復用價值呢?而且接口的名字和參數(shù)你真的可以一次確定么?
好,我們偷懶一下,先看看能否不定義接口。
Presenter:

Activity:

用這種方式p中包含了v對象,可以不寫任何回調就能直接觸發(fā)v的動作,而且不用寫接口和回調,甚至還可以支持一個v對應多個p的需求。但是如果你這個view被復用了,就得改一改。這種方案的一大壞處就是靈活性會比較低,但實際運用下來還不錯,算是一種偷懶的做法。
順便提及一下mvp的重要優(yōu)點:
1. 當activity意外重啟時presenter不會被重啟。
2. activity重啟時,presenter與activity會重新綁定,根據(jù)數(shù)據(jù)恢復activity狀態(tài)。
3. 而當activity真正銷毀時,對應地presenter應該隨之銷毀
這樣的好處可以解決以下2個很實際的問題:
不會每次翻轉屏幕都去顯示進度條,重新加載數(shù)據(jù)。
某些低端機,內存不足時activity被銷毀,但p會持有數(shù)據(jù),避免數(shù)據(jù)丟失。
1.4 谷歌的MVVM
我們看到了上述mvp的兩種實現(xiàn)方案:
第一種靈活但是寫起來復雜;第二種簡單,但是靈活性不足。
mvvm模式利用數(shù)據(jù)綁定的特性,自動化實現(xiàn)了第一種的回調模式,很棒對不?但也僅此而已。
先來看看谷歌的dataBinding是怎么做分層處理的吧:
1.先定義一個User類

2.在layout文件中綁定user

3.在java代碼中設置實現(xiàn)和數(shù)據(jù)

看完之后,是不是感覺很精妙。對,就是這么“精妙”,精妙到view都沒辦法被復用了。來看看這行代碼:

天哪!你怎么知道這個布局文件不會被復用,如果復用了,這里如果展示的是一個ad.info你該怎么處理。這個先不說,databinding還支持xml中寫java代碼,比如引入靜態(tài)方法和簡易判斷什么的。

干的漂亮,直接讓layout文件和java融為一體?,F(xiàn)在請你告訴我我該怎么復用這個layout文件。如果我在這里也寫了java的簡單判斷,java代碼中也寫了一些邏輯,我怎么快速定位問題。
這么寫帶來的嚴重后果就是,layout文件和java類強耦合,而且很難定位問題。你就永遠不知道這個邏輯是在java代碼中寫的還是xml中寫的了。
注意:我強烈不建議在xml中寫java代碼,它會增加定位問題的難度。
1.5 理想化的MVVM
理想化的mvvm最好是只用寫少量代碼就完成了具體需求的東西,超級酷!我希望我加載網絡成功后自動會更新到視圖上。
之前的做法:
建立xml,在activity中找到view,建立數(shù)據(jù)模型,寫好網絡回調,回調成功后依次設置view的狀態(tài)。
理想化的做法:
寫好數(shù)據(jù)模型,建立xml時直接綁定數(shù)據(jù)模型,在activity中寫好回調就行。
代碼如下:
數(shù)據(jù)模型:

布局文件:

Activity代碼:

如果真的可以這么寫,那么一切都會簡單很多。三個文件搞定了model,vm,v層。只是如果真的這么寫就會出現(xiàn)很多問題。比如你直接對json的數(shù)據(jù)模型
做了很多的處理,讓model的set和get方法不在純粹。如果你今天不用dataBinding了,以后要改就會相當困難?,F(xiàn)在再來復雜一點,我希望
對name進行判斷,根據(jù)name的數(shù)據(jù)不同讓view呈現(xiàn)View.VISIBLE, View.INVISIBLE, View.GONE三種狀態(tài)。
數(shù)據(jù)模型:

布局文件:

其余的文件不變。
我們增加了一個需求,只需要動兩個文件,是不是很贊。那么壞處就是對model的操作太多了,它已經不再純粹,可能未來還會做更多的事情。為了解決這個問題,谷歌說不要再動model了,我允許你在xml中寫java代碼:

這樣的做法就可以讓我們不動model類,只需要在xml中做邏輯操作。只可惜xml中肯定不能完成所有的視圖操作(比如動畫),而且xml是有復用價值的。所以我給出的結論就是,理想很豐滿,現(xiàn)實很骨感。
1.6 理想妥協(xié)于現(xiàn)實后的MVVM
我們不希望一個框架對現(xiàn)有的項目結構做太多的影響,框架影響到用于json解析的model是不能容忍的!這樣的話,我們就要建立一個給框架用的數(shù)據(jù)對象,所以vm現(xiàn)在就變成了一個和前面的json的model無關的獨立類。
需要注意的是:
vm僅僅處理和視圖展示內容有關的邏輯,比如對顯示的內容做格式化這樣的事情。除此之外不應處理其他的視圖邏輯。
數(shù)據(jù)模型:

viewModel:

布局文件:

Activity代碼:

這樣的做法就沒啥問題了,vm處理了邏輯,model變成純粹的類。而且也不用在xml中寫什么java代碼了,只要綁定vm的字段即可。view相關的java代碼都在activity中完成,如果view的邏輯出錯了直接進入activity中定位即可。
我們注意到了vm中做了加載數(shù)據(jù)的操作,應不應該這么寫呢?
不應該!viewModel就是view的數(shù)據(jù)模型,所以不應該圖省事,在vm中寫和view無關的業(yè)務邏輯。所以下面的這塊代碼不應該出現(xiàn)在vm中,而是應該放在別的地方。至于放在哪里合適,這就是后話了。

1.5 MVVM模式
看到了databinding的不足和問題,但我們也不能否認它的好處。它優(yōu)雅的幫我們搞定了回調,而且支持了數(shù)據(jù)的自動綁定?;谝陨系姆治觯易隽艘粋€小小的改造,讓layout和viewModel緊密聯(lián)系,如圖所示:

view層:具體的view,activity,fragment等,做ui展示、ui邏輯、ui動畫。
viewModel層:由插件自動生成的具體類,是view展示的數(shù)據(jù)的java抽象,僅能被model層直接操作。
model層:非ui層面的業(yè)務邏輯的實現(xiàn)。包含網絡請求,數(shù)據(jù)遍歷等操作,是很多具體類的抽象載體。
這里除了model層的定義很抽象外,其余的v、vm層我都給出了具體類做載體,下面詳細說下model層包含些什么。
model層:
因為model層是很多具體類的聚合,主要是做和展示無關的業(yè)務邏輯,在其中也會包含很多具體類。

要實現(xiàn)一個頁面的需求,我們可能會用到很多類,包括工具類和各種庫。這些類都提供了一個或多個功能,我們利用這些功能便可最終實現(xiàn)需求。而所有的調用應該是由一個類來進行的,這個類你可以叫做presenter,也可以叫做別的名字??傊褪且粋€執(zhí)行非ui層面邏輯的個體。
需要注意的是,這個p和mvp中的p是無關的,我僅僅是沒有找到很好的名字,才稱之為presenter。
二、如何使用Dbinding
2.1 編寫layout文件
首先我們先建立一個xml文件,這里推薦通過改模板的方式快速建立一個dbinding風格的layout文件。

在建立好的layout文件中的標簽里可以由標簽來定義viewModel,這個對象之后會和view的屬性進行綁定。目前,我們不用管這個類是否存在,我們只需要定義你想要的類和其對象的名字即可,比如:

定義好了變量名,我們就可以將其內部的字段與view的attribute進行綁定了:

這里我將user中的name字段與text這個屬性進行了綁定。(需要注意,這個text字段現(xiàn)在我們還沒創(chuàng)建,僅僅是寫了出來)。
現(xiàn)在這個textview展示的文字就是我們定義好的UserviewModel中的name的值了。通過對textview的了解,我們可以推測出name這個字段肯定是CharSequence類型的。
2.2 編寫layout文件時的問題
1.如何建立layout模板
idea中有個功能就是可以編輯文件模板,下面演示下如何定義這個模板。

2.為什么數(shù)據(jù)塊是用包裹,為什么叫這個名字呢?
因為這里的xml變成了兩部分,一個就是傳統(tǒng)的viewgroup包裹的布局文件,其余就是需要和布局文件綁定的vm。而vm的區(qū)塊用data做命名是比較合適的,因為vm本身就是數(shù)據(jù)。
這里需要格外注意的是,現(xiàn)在的layout文件已經不僅僅是一個單純的布局文件了,更合理的叫法是視圖+數(shù)據(jù)文件。
3.為什么這里定義變量是用標簽,而不是別的名字呢?
variable本身就是變量的意思,這個名稱是很合適的。當然如果寫過js的同學,會更加熟悉它的縮寫var。但這里的起名上,大家應該不會有什么爭議和容易理解錯誤的地方。
4.為什么是通過type和name這兩個屬性來定義一個vm?
在java世界中我們是通過:

來做變量的定義的。在xml文件中不存在什么相互調用的情況,定義的變量都是private的,所以省略了private這個關鍵字。至于,為什么變量的對象名用type,名字用name,這也是有原因的。
為了說清楚這個問題,我們先來看看jdk中Field這個類的部分代碼。

可見,這里的命名是參照了java中field的命名來的。這種命名方式會比較符合大眾直覺,明白了這個原因,相信以后定義的時候就不會有什么疑惑了。
5.viewModel的name字段該怎么取名?
既然我們的viewModel會和view進行綁定,而且view是有可能被復用的。所以這里的取名我強烈建議和view的意義有關。千萬不可脫離view的意義隨便取名字,這樣以后你用的時候就會很麻煩。簡單來說,你完全可以參考之前給view取id的做法來給viewModel取名字。
6.viewModel的type應該怎么寫?
既然我們名字搞定了,那么類名基本就出來了。這里需要注意的是,這里的類名是包含完整包名的。我強烈建議所有的viewModel都在一個包中,不要隨便放。因為viewModel以后可能會出現(xiàn)重命名和被刪除的情況,放在一個包下面方便管理。這里我是在vm這個包下面放所有的viewModel,所以就取了org.kale.vm.UserviewModel這樣一個名字。至于其他的viewModel的包名前綴我們也可以規(guī)范為org.kale.vm。
7.可以在同一個xml中寫兩個相同類型的viewModel么?
可以,但沒必要!
在java中會出現(xiàn)這樣的情況:

在一個類文件中定義了兩個相同類型(String)的field。但是在xml中這種情況是嚴格禁止的,也是完全沒必要的。因為viewModel是一個有
明確含義的對象,并不是基本類型。而且其綁定地view也是特定的,完全沒必要定義兩個相同類型的viewModel。順便提一下,兩個不同類型的
viewModel的name必須是不同的,這個和java的規(guī)則完全一致的。
8.真的不用寫具體的viewModel類么?
是的,不用。你在xml中定義好了

后,這個UserviewModel會通過插件(或通過快捷鍵)出現(xiàn)在相應的包下,你定義好就可以直接用了,沒必要關心具體的實現(xiàn)。這也是dbinding插件的一個強大之處!
9.如何在別的xml中復用已經定義好的類?
viewModel
的一大特性就是可復用,viewModel和view都可以是多對多的關系。比如你這個UserviewModel中包含了username這個字段,而
別的xml文件中正好需要這個UserviewModel,你完全可以把username定義到那個xml文件中。這樣兩個xml文件就會共用一個共同類
型的數(shù)據(jù)。復用的方式很簡單,就是在別的xml文件中寫上

就行。
10.如何知道一個vm是否已經存在?
目前如果已經存在的vm會有代碼提示的,如果沒有代碼提示,并且報紅的就是之前沒有的vm。
11.可以在一個xml文件中定義多個viewModel么?
當然可以,正如我所說的:viewModel是和view綁定的。一個界面中有多個不同模塊的view是很常見的,遇到這樣的情況你完全可以在xml中定義多個viewModel。要知道viewModel和view都是多對多的關系。
12.viewModel如何做全局改名、刪除、移動這樣的重構操作?
1.改名和改包名
這個就是和重構相關的問題了。
我們在xml中通過插件產生了viewModel,但如果要改包名和改變viewModel的類名的時候,最簡單快捷的方式是,進入到這個類的實體中,通過idea的重構工具進行修改。這樣所有的改動會自動同步到使用這個類的xml文件中了。當然,你也可以在這個類被調用的地方通過重構工具進行改名。

2.刪除
至于刪除某個viewModel也是一樣的,仍舊是對java類進行操作。刪除的時候注意排查下用到的地方,以免出錯。

13.viewModel中的字段如何做改名、刪除這樣的操作?
1.改名
我們先來看下插件會給我們通過我們的xml生成什么東西:

我們看到了我們定義的name字段和其get和set方法。如果我們突然想把這個“name”改名為“nickname”,或者是刪除這個name字段呢?做法就是直接重構name這個字段。
下面為了演示方便,減少干擾選項。我把name這個過于通用的字母先改為了nickname。我將演示如何將nickname通過idea的重構工具改為name。

2.刪除
因為idea對于databinding的支持力度很低(未來或許就可以通過重構工具做了),所以在重構字段的時候只能我們自己去排查了。我的排查方案是通過檢索當前類使用過的地方,來看下使用當前類的xml中有沒有使用過我要刪除的字段,如果有就進行處理,如果沒有就直接刪除。以此來避免刪除后出現(xiàn)程序出錯的問題。

14.如果我不想通過插件生成vm,可以手動寫么?
當然可以的,只需要在xml中加入ignore="true"就好。這樣插件就會忽略這個vm,交給開發(fā)者自己去建立。

15.如果插件生成的viewModel的屬性不能滿足我的要求,我可以自己配置生成規(guī)則么?
可以的,只需要做下面兩步:
1.在項目中的values下的dbinding_config.xml文件中,增加插件生成的規(guī)則:

2.在隨便一個類中寫入如下的java代碼:

這樣插件在自動生成代碼的時候就會讀取你新加入的規(guī)則,生成你想要的字段類型了。
2.3 編寫java代碼
上面說了那么多的layout文件的編寫策略,現(xiàn)在該說下如何寫java代碼了。java代碼主要做的工作就是綁定vm和layout文件,其余的操作就直接對vm進行就行了。對于復雜的界面,可以把ui無關的邏輯放入presenter中。
Activity:

MainPresenter:

2.4 編寫java代碼時的問題
1.presenter會被復用么?
會,但是極少。因為p是和某個特定的邏輯極其相關的,因此復用p的情況十分少見。
2.v和p的關系是什么樣的?
p可以做很多和業(yè)務邏輯相關的操作,但是vm必須是純粹的,vm對p完全不知情。
一個p會操作多個vm,一個vm也會被多個p使用。
注意:在本框架中vm是由框架自動生成的,強烈不建議對vm直接做增添與業(yè)務邏輯相關的事情。
3.有了mvvm框架后是否還需要fragment?
需要。因為activity中肯定會有不同的ui區(qū)塊,fragment既可以劃分不同的ui區(qū)域,又可以做到讓這些細顆粒度的ui能夠被復用,因此還是需要fragment來幫忙解耦ui,給activity減負的。
4.dbinding能否支持雙向綁定?
不準備支持。因為view的事件和vm的數(shù)據(jù)綁定其實是無關的,而且谷歌db的設計思路,本身就是單向的。如果非要套雙向綁定,我不能確保支持所有的view,所以目前是不準備支持的。
5.p對vm的操作是否必須在ui線程中?
可以在任何線程中操作vm,再也不用切回主線程操來操作作ui了。
6.如果p中的某些操作需要通知給activity,該怎么處理?
強烈建議用回調的方式做通知,不要把activity通過構造方法傳給p。如果傳了,就需要注意持有activity對象的問題,小心造成內存泄漏。
順便問一句,為什么fragment必須需要持有activity的引用呢?
首先,fragment也是ui,fragment中需要有很多和context有關的操作。比如啟動activity什么的,所以需要持有activity對象來做這些事情。最重要的是,fragment本身是可以對用戶行為產生事件的,而p絕對不會自己產生事件,必須通過外部觸發(fā)才行。因此p完全可以走純回調的方式,不必持有任何全局的context對象。

這個例子中,我通過參數(shù)傳入context,利用return返回結果。例子雖然簡單,但對于復雜的情況也是是如此。如果你覺得回調寫起來很麻煩,不妨試試用rxJava的形式做。
7.在mvvm框架中應該有什么編碼思路?
應該有明確的分層思路。在mvvm中我們應該把所有數(shù)據(jù)同步的事情交給框架,而不是自己去維護。將v層的邏輯(如:動畫,控件A改變引起的控件B改變等)獨立寫出;在p中獨立寫出數(shù)據(jù)對viewModel產生影響的邏輯。
下面舉個adapter的例子:

在數(shù)據(jù)來的時候,數(shù)據(jù)僅僅對vm進行綁定,不用考慮綁定后ui層面的邏輯:

8.如果我這個界面本身就沒有復用價值,能不能不用viewModel?
我們知道vm算是對xml文件的一種抽象,那么如果我這個界面本身就沒復用價值,能不能直接把p當作vm,直接綁定p中的字段呢?
這樣做當然是可行的。但問題就在于,你真的可以確保某個xml沒有復用價值么?如果你當前認為無復用價值的xml,以后卻要被復用了,那么你之前偷懶做的事情,對以后的人來說就是災難。雖然需要改一兩行代碼沒啥問題,但對于程序設計來說,你之前的設計方案和現(xiàn)在的需求產生了沖突,就得重新?lián)Q設計思路,這其實是有些嚴重的。
在android設計之初就給出了xml文件和java代碼分離的編碼
方案。但仍舊允許在java代碼中通過new出view來寫ui。xml和java分離的設計方案就是強制復用的思路,而activity中手動寫
view的編碼方案就是所謂的無復用思路。二者一類比,你就知道你需不需要寫vm了。
9.在Activity中應該做什么事情?
Activity中應該做一些view的配置工作。比如配置recyclerView的layoutmanager,設置下下拉刷新,view的動畫效果等等。
如果你的view的某種狀態(tài)的改變會引起其他view的改變,這個邏輯操作也需要放入activity中。很常見例子的就是,輸入密碼框的旁邊有個是否顯示明文密碼的按鈕,點擊按鈕會把密碼已明文的形式顯示出來,再點就變成了密文。這個東西是絕對屬于ui邏輯的范疇,所以應該寫在activity中,并且不應影響到vm和p。
10.我們真的不需要view的id了么?
我們仍舊需要id,只是不再需要findViewById了!
我們通過監(jiān)聽vm的某個字段來做相應的操作,但如上一個問題所說到的,密碼是否顯示的按鈕和輸入框的相互作用是不應該用vm做的。所以,在ui層面的邏輯中肯定還會有大量的id出現(xiàn)。幸好,databinding幫我們自動生成了id對象,再也不用寫findViewById了。
11.Adapter應該放在哪里?
adapter的位置比較尷尬,而且復用價值不高,實踐了很久后,我推薦放入p中。在dbinding中,我提供了ObservableArrayList這個list做數(shù)據(jù)的處理?,F(xiàn)在只需要對list進行操作即可,不用關心界面的更新問題。notifyDataSetChanged()會自動執(zhí)行。

12.什么該在xml中定義vm的字段?
當數(shù)據(jù)的變化會“直接”引起view的某個屬性改變,那么就應該在layout中寫一個vm的字段進行綁定。如果這個view的某個狀態(tài),是根據(jù)view其他的狀態(tài)改變而改變的,和數(shù)據(jù)層無關。那么就不應該定這個字段,而是用監(jiān)聽vm字段的方式來做。
監(jiān)聽的方案:

13.如果兩個頁面需要同步很多數(shù)據(jù),可以直接共用vm么?
當然可以!vm自身的自動綁定特性會讓兩個頁面共用數(shù)據(jù)變得十分簡單,可以通過viewModel.toSerializable()來將其序列化,然后在接收的地方通過:
得到它。得到后,你就可以方便的利用上個頁面?zhèn)鱽淼膙m進行l(wèi)ayout層面的綁定了。
雖然這種方式十分簡單,但不要濫用,它僅僅針對于兩頁面是含有共同vm的情況,其他情況我還是推薦通過回調、廣播、事件總線等方式做。要記得,vm雖好,但它不是萬能的。
請測試在低內存中這種方案會不會有bug。
14.如何對自動生成的vm做定制
插件僅僅能生成普通情況下的vm,它不可能知道你具體的邏輯和特殊需求。如果你要由這樣的需求,可以在new出vm的時候通過重載set方法來實現(xiàn)。

15.view的事件該如何綁定
因為vm僅僅是view的字段,vm的字段也應該和數(shù)據(jù)保持一致的,這時候你就會發(fā)現(xiàn)view的事件是不應該做vm綁定的,因為它不是數(shù)據(jù)。但,為了節(jié)約
findviewById和配置監(jiān)聽器的代碼,我提供了一個event對象來做界面的事件綁定。界面中所有view對象的事件都交給它來做就行。
layout文件:

java代碼:

相比起之前的做法,是必須要findviewbyid找到這個控件,然后設置監(jiān)聽器,為了一個頁面共用listener,減少代碼。就必須寫成這樣:

其實這樣的問題就在于view的設計監(jiān)聽和實現(xiàn)是脫離的,你必須要進行跳轉才能找到監(jiān)聽器的實現(xiàn),沒有聚合好。
參考自:
https://github.com/LyndonChin/MasteringAndroidDataBinding
http://www.itdecent.cn/p/add73330d106
http://www.itdecent.cn/p/e7b6ff1bc360