在前幾年興起了
MVVM架構(gòu)設(shè)計(jì)模式,最具有代表的框架就是
DataBinding,雖然這種設(shè)計(jì)架構(gòu)非常新穎,但是在使用中仍然還有很多痛點(diǎn),所以我當(dāng)時(shí)覺(jué)得短時(shí)間這個(gè)設(shè)計(jì)架構(gòu)可能不會(huì)太流行。

最近接手了新項(xiàng)目,使用的就是
MVVM,才發(fā)現(xiàn)只一兩年的功夫
MVVM的發(fā)展竟然這么快,已經(jīng)是Android開(kāi)發(fā)者必備的技能之一了。
DataBinding在剛開(kāi)始階段,最令我頭疼的就是數(shù)據(jù)處理的問(wèn)題,往往為了顯示數(shù)據(jù),我要在
XML中綁定
N多個(gè)字段,如果是一個(gè)中等以上的工程,還有更蛋疼的問(wèn)題,例如:
XML可能迫切的需要
if或者
switch這樣的判斷;在2018年,
Google推出
JetPack庫(kù),其中的
ViewModel+LIveData終于把
MVVM推上了新的高度。
使用
ViewModel需要依賴(lài)
lifecycle庫(kù):
implementation "android.arch.lifecycle:viewmodel:x.x.x" implementation "android.arch.lifecycle:extensions:x.x.x"
ViewModel的創(chuàng)建方法主要有兩種:
// 獲取FragmentActivity共享的ViewModel ViewModelProviders.of(FragmentActivity).get(ViewModel::class.java) // 獲取FragmentActivity共享的ViewModel ViewModelProviders.of(Fragment).get(ViewModel::class.java)
ViewModel的共享范圍主要有兩種:一種是
FragmentActivity,一種是
Fragment,可以根據(jù)自己的需要選擇共享的范圍。如果你想要一個(gè)
Application級(jí)別的
ViewModel,目前是不支持的,你可以自定義
Application持有一個(gè)
ViewModel,或者使用單例模式。
1、擴(kuò)大數(shù)據(jù)共享的應(yīng)用場(chǎng)景。
一般的數(shù)據(jù)共享是
Activity與
Fragment的數(shù)據(jù)傳遞,傳統(tǒng)做法是使用
setArguments(Bundle),這種方法有以下弊端:
setArguments會(huì)在
Fragment的哪個(gè)周期完成,要進(jìn)行異常判斷;setArguments中的數(shù)據(jù)可能會(huì)發(fā)現(xiàn)改變,如果是
Activity直接設(shè)置
Fragment的數(shù)據(jù),耦合性很高;Fragment會(huì)有很多的變量,影響可讀性和維護(hù)性。使用
ViewModel,可以避免以上的尷尬情況,需要什么數(shù)據(jù)就從
ViewModel中取:
Activity的
setArguments代碼,
Fragment也不用編寫(xiě)數(shù)據(jù)接收的方法;除此之外,自定義
View也可以得到
ViewModel,這樣某些功能耦合性非常強(qiáng)的自定義
View開(kāi)發(fā)更加便捷。不過(guò)需要注意的是
View的
context的上下文是
Activity類(lèi)型(不會(huì)是
Fragment)的,所以只能使用
Activity級(jí)別的數(shù)據(jù)共享。
2、解決DataBinding的視圖顯示問(wèn)題。
如果視圖的顯示需要很多的數(shù)據(jù),那么
XML就會(huì)變得越來(lái)越臃腫,并且迫切需要添加一些簡(jiǎn)單的判斷,例如:
如果A為空就顯示B,如果B為空就先是C,如果是C為空...
雖然
DataBinding支持三元運(yùn)算符,能夠滿(mǎn)足if判斷的需要,但是很顯然在
XML維護(hù)邏輯要比
Java或者
Kotlin要困難的多(無(wú)拼寫(xiě)錯(cuò)誤提示等)。所以我們非常需要把部分代碼從
XML分離出來(lái),
ViewModel就非常適合擔(dān)任這個(gè)角色。
修改前:
<?xml version="1.0" encoding="utf-8"?> <layout> <data> <variable name="A" type="String" /> <variable name="B" type="String" /> <variable name="C" type="String" /> </data> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:maxLines="4" android:ellipsize="middle" android:text="A != null ? A : B != null ? B : C" /> ... </layout>
修改后:
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="viewModel"
type="ViewModel" />
</data>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="4"
android:ellipsize="middle"
android:text="@{viewModel.getShowContent()}" />
... </layout>
剛才我們已經(jīng)討論了
ViewModel的用法,但是還有一個(gè)問(wèn)題沒(méi)有解決,那就是數(shù)據(jù)更新的問(wèn)題,解決這個(gè)問(wèn)題的最佳方式就是觀(guān)察者模式,但是如果沒(méi)有處理好觀(guān)察者的注冊(cè)和解綁很容易出現(xiàn)內(nèi)存溢出。
LiveData就可以完美的解決這個(gè)問(wèn)題。
我們需要添加
LiveData的依賴(lài):
implementation "androidx.lifecycle:lifecycle-livedata:2.1.0"
下面是一個(gè)簡(jiǎn)單的示例:
// 名為openDrawer的Boolean類(lèi)型的LiveData
public final MutableLiveData<Boolean> openDrawer = new MutableLiveData<>(); // 更新openDrawer
openDrawer.setValue(true) // 觀(guān)察openDrawer 的值的變化
openDrawer.observe(this, aBoolean -> {
Toast.makeText(this, "${aBoolean}", Toast.LENGTH_SHORT).show();
});
LiveData的子類(lèi)是
MutableLiveData,內(nèi)部有
value屬性保存最新的值,訂閱
LiveData的變化,直接調(diào)用
LiveData.observe():
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
owner:注冊(cè)的周期,會(huì)在owner銷(xiāo)毀的時(shí)候,解綁觀(guān)察者。
observer:觀(guān)察的值發(fā)生變化的回調(diào)函數(shù)
owner直接使用
Activity或者
Fragment即可。如果你還不了解
Lifecycle的使用,可以查看一下相關(guān)的資料。
最后我畫(huà)了一張架構(gòu)圖,總結(jié)了一下最新的
MVVM的使用架構(gòu):
網(wǎng)頁(yè)題目:Android開(kāi)發(fā)者必備的技能你會(huì)嗎?MVVM最新學(xué)習(xí)心得!-創(chuàng)新互聯(lián)
網(wǎng)站URL:http://www.chinadenli.net/article36/dsoopg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、云服務(wù)器、域名注冊(cè)、用戶(hù)體驗(yàn)、網(wǎng)站排名、App開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容