初探Jetpack(一) -- ViewModel

一、JetPack 簡介

以前在沒有 Jetpack 的時候,大家項目中最常使用的就是 MVP 或者 MVVM 等設計模式來解耦邏輯和UI,當然這非常考驗個人的設計能力和經驗。
Google 貌似也意識到了這個問題,在 2018推出了一個全新的架構組件庫 – Jetpack。
Jetpack 適合一個開發組件工具庫,它的主要目的是幫助我們編寫出更加簡潔的代碼,並簡化我們的開發開發特點;Jetpack 它不依賴任何 Android 系統版本,它定義在 androidx 中,並擁有非常好的向下兼容。

首先,看一張 Jetpack 的全家桶:
在這裏插入圖片描述
官網文檔:Jetpack

可以看到 Jetpack 幾乎覆蓋了開發所有的部分;目前 Google 主推的架構就是 MVVM,所以 Jetpack 其實就是專門爲 MVVM 設計的架構組件。

都 2020 了,那肯定也要學習一下 Jetpack 組件了,開衝!!

首先,先學習 ViewModel,

二、ViewModel 介紹

在傳統開發模式下,Activity、fragment 等UI任務繁瑣,又要負責邏輯,也要負責 UI,往往在一個比較大型的項目,一個 Activity 幾千行代碼算少的,讓人看了就沒下手的慾望,這也爲啥衍生了 MVP、MVVM 的原因;
而使用 ViewModel 的一個很重要的作用,就是可以爲 Activity 分擔一部分工作,它是專門用於存放於界面相關的數據的。也就是說,只要是界面上能看到的東西,它的變量都應該放在 ViewModel 中,而不是 Activity,這樣就可以一定程序上減少 Activity 的邏輯。

另外,ViewModel 還有一個特性,就是當手機旋轉等非正常退出時,它自身不會重建,即數據不會丟失,比如 Activity 在屏幕旋轉時,會重建,從而導致數據丟失,雖然可以使用 onSaveInstanceState() 從onCreate()方法獲取,但通過 ViewModel 就不用擔心這個。
ViewModel 的生命週期如下:
在這裏插入圖片描述

三、基本用法

首先你需要創建一個 androidx 的工程,如果要使用 ViewModel,還需要 關聯以下依賴:

    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

通常來講,比較好的規範就是給 每一個 Activity 或者 Fragment 創建一個對應的 ViewModel。
所以,這裏我們也創建一個於 activity 對應的 MainViewModel,並讓它集成 ViewModel,如:

class MainViewModel() : ViewModel() {
    var counter = 0;
}

xml 中寫一個按鈕,每次就加1,並通過 textview 顯示出來

    <TextView
        android:id="@+id/infoText"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:gravity="center"
        />
    <Button
        android:id="@+id/textcounter"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Plus one"
        />

接着,則是通過ViewModelProvider 創建 ViewModel 的實例,由於 ViewModel 有自己的生命週期,並且生命週期長於activity,如果再 oncreate 創建實例,這樣每次都會創建一個新的實例,這樣就無法保存數據了。所以,ViewModel 的實例創建應該這樣:

 viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

所以,完整程序如下:

 val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

 textcounter.setOnClickListener{
     viewModel.counter ++;

     infoText.text = viewModel.counter.toString()
 }

 infoText.text = viewModel.counter.toString()

效果如下:
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/2020061107521018.png在這裏插入圖片描述
可以看到,當旋轉屏幕,數據也不會發現變化

3.1 向 ViewModel 傳遞參數

上一節,ViewModel 並沒有構造參數,如果我們要想它傳遞初始值怎麼辦呢?比如傳遞一個數值。

這個問題,可以通過 ViewModelProvider.Factory 來實現,首先,修改MainViewModel,如:

class MainViewModel(count:Int ):ViewModel() {
    var counter = count
}

然後新建一個 MainViewModelFactory 並讓它實現 ViewModelProvider.Factory 接口,如下:

class MainViewModelFactory(val count:Int):ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {

        return MainViewModel(count) as T
    }
}

可以看到,MainViewModelFactory 的構造參數接受一個 count,並在 create 的時候,對 MainViewModel 初始化並傳遞數值。

接着,修改一下代碼:

ViewModelProvider(this,MainViewModelFactory(5)).get(MainViewModel::class.java)

可以看到數值一開始就改變了:
在這裏插入圖片描述

後面的文章,我們再繼續深入瞭解 ViewModel

參考:<第一行代碼> 第三版

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章