MVVM-LiveData[Kotlin 項(xiàng)目實(shí)戰(zhàn)]

前言

??廢話少說(shuō)颊亮,直接上點(diǎn)干貨柴梆。https://github.com/yiweituoxie/MyKotlin ,代碼結(jié)構(gòu)如下圖

project.png

效果圖.gif

??這是一個(gè)簡(jiǎn)單介紹在MVVM框架下使用RxJava2+Retrofit2請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù)的小項(xiàng)目终惑,接下來(lái)我會(huì)不斷地在這個(gè)項(xiàng)目上更新一些平時(shí)用到的好用的特性或者功能绍在,同時(shí)也會(huì)發(fā)布對(duì)應(yīng)的文章。首先要聲明的是雹有,這篇文章和這個(gè)項(xiàng)目暫時(shí)是針對(duì)MVVM的初學(xué)者或者剛開(kāi)始使用MVVM的同學(xué)的偿渡,所以有大篇幅都在介紹官方的或者是針對(duì)項(xiàng)目的代碼進(jìn)行說(shuō)明。
??平常用習(xí)慣MVP的同學(xué)也可以在我的github上找到一個(gè)相對(duì)比較成熟的MVP項(xiàng)目霸奕,歡迎交流與push https://github.com/yiweituoxie/Mvp-Kotlin
??想要更加詳細(xì)地了解MVVM或者M(jìn)VP的同學(xué)可以轉(zhuǎn)彎到官方https://github.com/googlesamples/android-architecture?utm_source=tuicool
官方的Sample中不但介紹了MVVM的兩種實(shí)現(xiàn)(LiveData溜宽,DataBinding),同時(shí)也向開(kāi)發(fā)者提供了一些非常好用的類质帅,例如SingleLiveEvent适揉。

MVVM劇情介紹

??為了不落俗套,我在這邊就跳過(guò)故事的背景介紹煤惩,想要了解MVVM框架的可以移步到https://www.zhihu.com/question/30976423/answer/50224601嫉嘀。故事的梗概就是記述我們的大偵探夏洛克ViewModel幫助他的兩個(gè)委托人Model組織和View組織找到各自的成員在對(duì)方組織里面的另一半的故事,那如果是這樣的故事魄揉,又怎么能區(qū)分這不是波洛的故事而是福爾摩斯的故事呢剪侮,對(duì),你沒(méi)猜錯(cuò)洛退,華生在最新一季的MVVM中票彪,閃亮登場(chǎng)了。事實(shí)上不狮,在這一季之前,MVVM中在旱,我們看到夏洛克ViewModel辦案非常費(fèi)勁摇零,在很多觀眾的代碼前,時(shí)常要深入到M和V里面桶蝎,插手本來(lái)不屬于它的事務(wù)驻仅,這也讓很多新來(lái)的觀眾一頭霧水谅畅,說(shuō)好的解耦呢,說(shuō)好的分離呢噪服,說(shuō)好的效率呢毡泻。對(duì)MVVM的口碑可以說(shuō)分歧很大,有不少新來(lái)的觀眾紛紛棄劇粘优。在收視率的壓力下仇味,導(dǎo)演兼編劇Google推出新角色華生LiveData可以說(shuō)是眾望所歸。
??網(wǎng)上有相當(dāng)多介紹LiveData和ViewModel的文章雹顺,可以說(shuō)是五花八門琳瑯滿目丹墨,其中不乏優(yōu)秀的影評(píng),但是很多新老觀眾總結(jié)起來(lái)都表示挺暈的嬉愧,其實(shí)不妨看看導(dǎo)演自己怎么介紹角色贩挣。在Google的官網(wǎng)上對(duì)LiveData有詳細(xì)的介紹:

LiveData.png

??LiveData屬于android.arch.lifecycle:livedata-core這個(gè)包下面的一個(gè)類,包名已經(jīng)很顯然地表明没酣,LiveData本身是和內(nèi)存回收有關(guān)的王财。第一句話,LiveData是一個(gè)可以在給定生命周期內(nèi)觀察到的數(shù)據(jù)持有者類裕便,沒(méi)錯(cuò)绒净,非常官方,后面緊接著是LiveData的內(nèi)部原理闪金,其實(shí)翻譯成好理解一點(diǎn)的話(并不嚴(yán)謹(jǐn))疯溺,就是LiveData可以綁定多個(gè)觀察者,并且會(huì)跟隨觀察者的生命周期存活哎垦,當(dāng)活動(dòng)觀察者的數(shù)量在0和1之間發(fā)生變化時(shí)囱嫩,可以得到通知。而在最后一段漏设,則直截了當(dāng)?shù)卣f(shuō)墨闲,它和ViewModel的親密關(guān)系。
??翻開(kāi)ViewModel的介紹郑口,作為一個(gè)大名鼎鼎的Class鸳碧,竟然在自己的個(gè)人空間里面,直接了當(dāng)?shù)脭[明了和LiveData關(guān)系犬性,可以說(shuō)是男友力Max:

ViewModel.png

??“ViewModel通常通過(guò)LiveData或Android DataBinding公開(kāi)這些信息”瞻离,事實(shí)上,有相當(dāng)多的人還在使用AndroidDataBinding乒裆,而用過(guò)的人套利,我相信都或多或少感受到它的不方便,對(duì)于有代碼潔癖的小伙伴來(lái)說(shuō),設(shè)置有點(diǎn)膈應(yīng)肉迫。所以照顧到大家得感受验辞,官網(wǎng)只貼出了ViewModel和LiveData的合影,作為官方認(rèn)證的CP喊衫,觀眾還要說(shuō)啥跌造,高舉起來(lái),舔就完事了族购。

public class UserActivity extends Activity {

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.user_activity_layout);
         final UserModel viewModel = ViewModelProviders.of(this).get(UserModel.class);
         viewModel.userLiveData.observer(this, new Observer() {
            @Override
             public void onChanged(@Nullable User data) {
                 // update ui.
             }
         });
         findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                  viewModel.doAction();
             }
         });
     }
 }
public class UserModel extends ViewModel {
     public final LiveData<User> userLiveData = new LiveData<>();

     public UserModel() {
         // trigger user load.
     }

     void doAction() {
         // depending on the action, do necessary business logic calls and update the
         // userLiveData.
     }
 }

??上面的代碼可以說(shuō)是相當(dāng)?shù)鼐?jiǎn)壳贪,在UserActivity中,viewModel的userLiveData綁定到UserActivity上联四,當(dāng)調(diào)用可以發(fā)現(xiàn)viewModel的doAction方法改變userLiveData的值是撑碴,userLiveData會(huì)自動(dòng)通知它的觀察者(也就是UserActivity):“我變了,你要不要做點(diǎn)事情”〕眨可以看到醉拓,ViewModel里是并沒(méi)有View的任何邏輯或?qū)ο蠓椒ǎ峭ㄟ^(guò)定義LiveData收苏,通知LiveData的觀察者亿卤。相信你很容易就能推理得出,開(kāi)發(fā)者可以在任意的View(界面)上使用UserModel鹿霸,比如說(shuō)登錄界面排吴,注冊(cè)界面,用戶管理界面等等懦鼠,只需要監(jiān)聽(tīng)界面關(guān)心的數(shù)據(jù)就可以了钻哩。這也就是ViewModel的復(fù)用性和低耦合的優(yōu)點(diǎn)。

我的小劇場(chǎng)

??小劇場(chǎng)是一個(gè)簡(jiǎn)單的登錄界面肛冶,麻雀雖小街氢,但五臟俱全,開(kāi)篇的時(shí)候已經(jīng)介紹過(guò)了睦袖,代碼是基于RxJava2+Retrofit2進(jìn)行網(wǎng)絡(luò)請(qǐng)求的珊肃,正是如此,ViewModel需要通知View的信息就包括馅笙,正在請(qǐng)求伦乔,請(qǐng)求成功和請(qǐng)求失敗三種信息。所以在ViewModel中董习,定義了三個(gè)LiveData烈和,分別是userInfo,loadingMessage皿淋,toastStringMessage斥杜,分別保存請(qǐng)求成功的用戶信息虱颗,是否正在請(qǐng)求,異常信息蔗喂,并且在對(duì)應(yīng)的方法中修改它們的值。


LoginViewModel.png

??對(duì)應(yīng)的高帖,我們需要在View(LoginActivity)中創(chuàng)建一個(gè)ViewModel的實(shí)例缰儿,當(dāng)然少不了的,就是對(duì)關(guān)心的LiveData綁定觀察者散址,也就是View本身乖阵。


LoginActivity.png

??為什么要一再?gòu)?qiáng)調(diào)是關(guān)心的LiveData呢?這也正是上面提到過(guò)的復(fù)用性和低耦合了预麸,舉個(gè)簡(jiǎn)單的例子瞪浸,在用戶管理界面,使用同樣一個(gè)UserModel進(jìn)行數(shù)據(jù)的獲取吏祸,但是這個(gè)時(shí)候加載用戶的信息对蒲,首先會(huì)獲取本地保存的信息,同時(shí)為了保證數(shù)據(jù)的一致性贡翘,還會(huì)獲取服務(wù)器的用戶信息(比如在其它地方修改過(guò)用戶的信息)蹈矮。出于對(duì)UX的考慮,等待框是不會(huì)出現(xiàn)的鸣驱,只需要默默地同步信息就可以了泛鸟。那么,在用戶管理界面踊东,就并不需要監(jiān)聽(tīng)loadingMessage北滥。
?? 這其實(shí)也側(cè)面地說(shuō)明了,View和ViewModel的關(guān)系是多對(duì)多的闸翅,也就是View中可以有多個(gè)ViewModel再芋,ViewModel也可以被多個(gè)View綁定。

多說(shuō)兩句

??細(xì)心的同學(xué)可能已經(jīng)留意到同樣是被監(jiān)聽(tīng)的數(shù)據(jù)缎脾,loadingMessage 繼承自MutableLiveData祝闻,而 toastStringMessage則繼承前言提到過(guò)的 SingleLiveEvent。這究竟是出于什么考慮呢遗菠?

class LoadingMessage : MutableLiveData<Boolean>()
class ToastStringMessage : SingleLiveEvent<String>() {
    override fun setValue(t: String?) {
        super.setValue(t)
        super.setValue(null)
    }

    override fun postValue(t: String?) {
        super.postValue(t)
        super.postValue(null)
    }
}

??這里就涉及到更加規(guī)范的ViewModel和LiveData的使用联喘,有興趣的同學(xué)可以看一下官方的建議,https://medium.com/androiddevelopers/viewmodels-and-livedata-patterns-antipatterns-21efaef74a54辙纬,作者提出了更多的使用建議豁遭,相信看完以后,你會(huì)對(duì)LiveData有更深的認(rèn)識(shí)贺拣。中文翻譯在https://zhuanlan.zhihu.com/p/33206893蓖谢。
??Chow Chow &C U Next Time

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捂蕴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子闪幽,更是在濱河造成了極大的恐慌啥辨,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盯腌,死亡現(xiàn)場(chǎng)離奇詭異溉知,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)腕够,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門级乍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人帚湘,你說(shuō)我怎么就攤上這事玫荣。” “怎么了大诸?”我有些...
    開(kāi)封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵捅厂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我底挫,道長(zhǎng)恒傻,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任建邓,我火速辦了婚禮盈厘,結(jié)果婚禮上永毅,老公的妹妹穿的比我還像新娘孟岛。我一直安慰自己,他們只是感情好票灰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布注簿。 她就那樣靜靜地躺著契吉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诡渴。 梳的紋絲不亂的頭發(fā)上捐晶,一...
    開(kāi)封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音妄辩,去河邊找鬼惑灵。 笑死,一個(gè)胖子當(dāng)著我的面吹牛眼耀,可吹牛的內(nèi)容都是我干的英支。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼哮伟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼干花!你這毒婦竟也來(lái)了妄帘?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤池凄,失蹤者是張志新(化名)和其女友劉穎抡驼,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體修赞,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡婶恼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了柏副。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蚣录,死狀恐怖割择,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情萎河,我是刑警寧澤荔泳,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站虐杯,受9級(jí)特大地震影響玛歌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜擎椰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一支子、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧达舒,春花似錦值朋、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至贯底,卻和暖如春丰辣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背禽捆。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工笙什, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人睦擂。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓得湘,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親顿仇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子淘正,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,077評(píng)論 25 707
  • 用兩張圖告訴你摆马,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 12,714評(píng)論 2 59
  • 前言: 本文主要是對(duì)常見(jiàn)設(shè)計(jì)模式的一些分析鸿吆,以及講述在Android項(xiàng)目中實(shí)現(xiàn)Mvvm模式的兩種方式囤采。通過(guò)Data...
    Yagami3zZ閱讀 45,118評(píng)論 29 117
  • “Always believe that something wonderful is about to happ...
    張凱麗閱讀 1,465評(píng)論 0 1
  • 聽(tīng)到東華的聲音,雖然剛剛滾滾的一番話已經(jīng)讓她的氣消了一大半惩淳,但是鳳九還是不想跟他說(shuō)話蕉毯。 "小白"紫色的衣角出現(xiàn)在鳳...
    芥末啤閱讀 2,715評(píng)論 5 18