一、ViewModel + LiveData + DataBinding 核心要點(diǎn)
1、ViewModel 使用要點(diǎn)
ViewModel 架構(gòu)組件 是 視圖 View 與 數(shù)據(jù)模型 Model 之間 數(shù)據(jù)交互的 橋梁 ;
傳統(tǒng) Android 開(kāi)發(fā)中 , 視圖 View 與 數(shù)據(jù)模型 Model 都在 Activity 中維護(hù) , 導(dǎo)致 二者有很高的耦合度 , 不利于代碼維護(hù) ;
引入了 ViewModel 架構(gòu)組件后 , 視圖 View 與 數(shù)據(jù)模型 Model 之間實(shí)現(xiàn)了解耦 , 同時(shí)也能 保證二者之間的雙向數(shù)據(jù)交互 , 減少了 Activity 代碼量 , 增加了應(yīng)用程序的可維護(hù)性 ;
ViewModel 使用要點(diǎn) :
-
首先 , 創(chuàng)建 自定義 ViewModel 視圖模型 類(lèi) , 繼承 androidx.lifecycle.ViewModel 類(lèi) , 該類(lèi)就是 要設(shè)置到 視圖 中的 數(shù)據(jù)模型 ;
- 與 DataBinding 結(jié)合使用時(shí) , 在 DataBinding 布局中設(shè)置的就是該 視圖模型 類(lèi)對(duì)象 ;
- 該 ViewModel 類(lèi)中 , 還 使用了 LiveData , 可以實(shí)時(shí)監(jiān)聽(tīng)數(shù)據(jù)改變 , 以更新界面 UI 組件 ;
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class MyViewModel: ViewModel() {
lateinit var number: MutableLiveData<Int>
init {
number = MutableLiveData()
number.value = 0
}
}
-
然后 , 在 Activity 系統(tǒng)組件 中 獲取視圖模型 ;
- 創(chuàng)建 ViewModelProvider 對(duì)象 , 傳入如下兩個(gè)參數(shù) :
- ViewModelStoreOwner 對(duì)象 , 就是 本 Activity 組件 ;
- ViewModelProvider.Factory 對(duì)象 , 通過(guò)調(diào)用 ViewModelProvider.AndroidViewModelFactory 函數(shù) 獲取 ;
- 調(diào)用 ViewModelProvider#get 函數(shù) , 獲取自定義 ViewModel 類(lèi) ;
- 創(chuàng)建 ViewModelProvider 對(duì)象 , 傳入如下兩個(gè)參數(shù) :
var viewModel: MyViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application)).get(MyViewModel::class.java)
-
最后 , 將 視圖模型中的數(shù)據(jù) 設(shè)置到 視圖組件 中 ;
- 與 DataBinding 結(jié)合使用時(shí) , 將 ViewModel 對(duì)象設(shè)置到 DataBinding 布局中 ;
// 3. 向布局中設(shè)置數(shù)據(jù)模型對(duì)象
activityMainBinding.viewmodel = viewModel
2、LiveData 使用要點(diǎn)
LiveData 是基于 ViewModel 的 , 是 對(duì) ViewModel 數(shù)據(jù)維護(hù)的一個(gè)補(bǔ)充 ;
在 Activity 中使用代碼可以將 ViewModel 初始數(shù)據(jù) 設(shè)置給 視圖組件 , 進(jìn)行 初始狀態(tài)顯示 ; 如果 在運(yùn)行過(guò)程中 , ViewModel 中的數(shù)據(jù)發(fā)生了變化 , 如何將變化應(yīng)用到視圖組件中 , 在視圖中顯示最新的數(shù)據(jù)內(nèi)容 , 此時(shí)就用到了 LiveData 組件 ;
在 ViewModel 的基礎(chǔ)上 , 通過(guò) 引入 LiveData , 可以將 運(yùn)行過(guò)程中 ViewModel 中的 Model 模型數(shù)據(jù)改變 通知 視圖 View , 令視圖組件顯示最新的數(shù)據(jù)內(nèi)容 ;
在 ViewModel 中使用了 LiveData 后 , 必須調(diào)用 LiveData#observe 函數(shù) 為 LiveData 設(shè)置 androidx.lifecycle.Observer 監(jiān)聽(tīng)器 , 如果 監(jiān)聽(tīng)到了 LiveData 數(shù)據(jù)變化 , 直接 回調(diào) 監(jiān)聽(tīng)器的 androidx.lifecycle.Observer#onChanged 函數(shù) , 在該回調(diào)函數(shù)中執(zhí)行 更新視圖 操作 ;
LiveData 使用核心要點(diǎn) :
- 首先 , 在 自定義 ViewModel 類(lèi)中 , 定義 MutableLiveData 成員 ;
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class MyViewModel: ViewModel() {
lateinit var number: MutableLiveData<Int>
init {
number = MutableLiveData()
number.value = 0
}
}
- 然后 , 將 在 DataBinding 布局 中 , 設(shè)置該 自定義 ViewModel 類(lèi)型實(shí)例對(duì)象 作為綁定的數(shù)據(jù) ;
<data>
<variable
name="viewmodel"
type="kim.hsl.vld.MyViewModel" />
</data>
- 再后 , 在 Activity 組件中 獲取 DataBinding 布局對(duì)應(yīng)的 ActivityMainBinding 實(shí)例對(duì)象 , 為 Activity 組件設(shè)置布局文件;
// 1. 加載數(shù)據(jù)綁定布局
var activityMainBinding: ActivityMainBinding =
DataBindingUtil.setContentView<ActivityMainBinding>(
this,
R.layout.activity_main
)
- 最后 , 設(shè)置 LiveData 在 DataBinding 中觀察者生命周期所有者 ;
// 4. 設(shè)置 LiveData 在 DataBinding 中觀察者生命周期所有者
activityMainBinding.lifecycleOwner = this
在最后調(diào)用的 ViewDataBinding#setLifecycleOwner 函數(shù) , 設(shè)置 LiveData 在 DataBinding 布局 中 的 觀察者 的 生命周期所有者 ;
LiveData 如果要生效 , 需要為其 設(shè)置 androidx.lifecycle.Observer 觀察者 , 如果 監(jiān)聽(tīng)到了 LiveData 數(shù)據(jù)變化 , 直接 回調(diào) 監(jiān)聽(tīng)器的 androidx.lifecycle.Observer#onChanged 函數(shù) ;
DataBinding 布局 生成對(duì)應(yīng)的 ViewDataBinding 類(lèi) , 調(diào)用 ViewDataBinding#setLifecycleOwner 函數(shù) , 傳入的 LifecycleOwner 實(shí)例對(duì)象 , 該對(duì)象就是 LiveData 的觀察者 , 如果不設(shè)置該項(xiàng) , LiveData 發(fā)生數(shù)據(jù)改變后 , 則 不會(huì)通知 UI 組件進(jìn)行數(shù)據(jù)更新 ;
Activity 組件繼承了 AppCompatActivity ,
- AppCompatActivity 繼承了 FragmentActivity ,
- FragmentActivity 繼承了 ComponentActivity ,
- ComponentActivity 實(shí)現(xiàn)了 LifecycleOwner 接口 ;
- FragmentActivity 繼承了 ComponentActivity ,
因此可以 將 Activity 作為 LifecycleOwner 設(shè)置給 ViewDataBinding 數(shù)據(jù)綁定布局類(lèi) ;
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ContextAware,
LifecycleOwner,
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner,
ActivityResultRegistryOwner,
ActivityResultCaller {
3、DataBinding 使用要點(diǎn)
DataBinding 的主要作用是 綁定 下面兩個(gè)元素 :
- 數(shù)據(jù)模型 Model / 視圖模型 ViewModel
- 視圖 View
DataBinding 中除了綁定 數(shù)據(jù)模型 Model 之外 , 還可以直接綁定 視圖模型 ViewModel , 這是 DataBinding + ViewModel 組合用法 , 如果 ViewModel 中使用了 LiveData 變量 , 則變成了 DataBinding + ViewModel + LiveData 組合用法 ;
DataBinding 使用核心要點(diǎn) :
- 首先 , 啟用 DataBinding , 在 build.gradle 構(gòu)建腳本 中的 " android / defaultConfig " 配置塊 中 , 配置如下內(nèi)容以 啟用 DataBinding ;
// 啟用 DataBinding
dataBinding {
enabled = true
}
-
然后 , 將 普通布局文件 轉(zhuǎn)換為 DataBinding 布局文件 , 將光標(biāo)放在布局左上角 , 按下 " Alt + 回車(chē) " 組合鍵 , 選擇 " Convert to data binding layout " 選項(xiàng) ;
-
再后 , 在 DataBinding 中配置 Model 數(shù)據(jù)模型對(duì)象 或者 ViewModel 視圖模型對(duì)象 , 在本示例中配置的是 ViewModel 實(shí)例對(duì)象 ;
- 配置 Model 數(shù)據(jù)模型對(duì)象 , 那么就是 DataBinding 簡(jiǎn)單使用 ;
- 配置 ViewModel 視圖模型對(duì)象 , 那么就是 DataBinding + ViewModel 組合使用 ;
<data>
<variable
name="viewmodel"
type="kim.hsl.vld.MyViewModel" />
</data>
- 最后 , 在 Activity 組件中 , 加載 DataBinding 布局 并 獲取對(duì)應(yīng)的 ViewDataBinding 對(duì)象 , 向該 ViewDataBinding 對(duì)象中設(shè)置 ViewModel 對(duì)象 , 即可完成數(shù)據(jù)綁定 實(shí)現(xiàn)了 DataBinding + ViewModel 組合使用 , 在最后為 LiveData 設(shè)置觀察者 , 實(shí)現(xiàn)了 DataBinding + ViewModel + LiveData 組合使用 ;
// 1. 加載數(shù)據(jù)綁定布局
var activityMainBinding: ActivityMainBinding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
// 2. 獲取數(shù)據(jù)模型
var viewModel: MyViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application)).get(MyViewModel::class.java)
// 3. 向布局中設(shè)置數(shù)據(jù)模型對(duì)象
activityMainBinding.viewmodel = viewModel
// 4. 設(shè)置 LiveData 在 DataBinding 中觀察者生命周期所有者
activityMainBinding.lifecycleOwner = this
二、ViewModel + LiveData + DataBinding 代碼示例
代碼示例 :文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-428474.html
- GitHub : https://github.com/han1202012/ViewModel_LiveData_DataBinding
- CSDN : https://download.csdn.net/download/han1202012/87736717
1、ViewModel + LiveData 代碼
定義 ViewModel 視圖模型類(lèi) , 該類(lèi)繼承了 androidx.lifecycle.ViewModel 類(lèi) ;
在該自定義 ViewModel 類(lèi)中 , 定義了 MutableLiveData 成員 , 這是 LiveData 實(shí)現(xiàn) , 用于在 運(yùn)行過(guò)程中 , 一旦 ViewModel 數(shù)據(jù)發(fā)生改變 , 就 通知 View 視圖組件 , 更新數(shù)據(jù)顯示 ;
LiveData 生效需要 為 MutableLiveData 設(shè)置 androidx.lifecycle.Observer 監(jiān)聽(tīng)器 , 當(dāng)數(shù)據(jù)發(fā)生改變時(shí) , 就會(huì) 回調(diào) 監(jiān)聽(tīng)器中的 androidx.lifecycle.Observer#onChanged 回調(diào)函數(shù) ;
代碼示例 :
package kim.hsl.vld
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class MyViewModel: ViewModel() {
lateinit var number: MutableLiveData<Int>
init {
number = MutableLiveData()
number.value = 0
}
fun plus(): Unit {
number.value = number.value?.plus(1)
}
fun minus(): Unit {
number.value = number.value?.minus(1)
}
fun reset(): Unit {
number.value = 0
}
}
2、build.gradle 構(gòu)建腳本 - 啟用 DataBinding
在 build.gradle 構(gòu)建腳本 中的 " android / defaultConfig " 配置塊 中 , 配置如下內(nèi)容以 啟用 DataBinding ;
配置內(nèi)容 :
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}
android {
namespace 'kim.hsl.vld'
compileSdk 32
defaultConfig {
applicationId "kim.hsl.vld"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
dataBinding{
enabled = true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
3、DataBinding 布局文件 - 配置 ViewModel 類(lèi)
首先 , 將 普通布局文件 轉(zhuǎn)換為 DataBinding 布局文件 , 將光標(biāo)放在布局左上角 , 按下 " Alt + 回車(chē) " 組合鍵 , 選擇 " Convert to data binding layout " 選項(xiàng) ;
然后 , 在 DataBinding 中配置 ViewModel 視圖模型對(duì)象 ;
在 TextView 中顯示文本時(shí) , 設(shè)置如下屬性 , 由于顯示的內(nèi)容是 Int 數(shù)字 , 需要轉(zhuǎn)為 String 后才能顯示 ;
android:text="@{String.valueOf(viewmodel.number)}"
為 Button 組件設(shè)置點(diǎn)擊事件時(shí) , 如果要 調(diào)用配置的 ViewModel 對(duì)象的函數(shù) , 需要使用 ()->對(duì)象.函數(shù)()
的形式進(jìn)行調(diào)用 , 如下示例 :
android:onClick="@{()->viewmodel.plus()}"
DataBinding 布局文件代碼 :
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewmodel"
type="kim.hsl.vld.MyViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(viewmodel.number)}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+1"
android:onClick="@{()->viewmodel.plus()}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/button2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-1"
android:onClick="@{()->viewmodel.minus()}"
app:layout_constraintStart_toEndOf="@+id/button"
app:layout_constraintEnd_toStartOf="@+id/button3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="158dp" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="reset"
android:onClick="@{()->viewmodel.reset()}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/button2"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
4、Activity 系統(tǒng)組件代碼 - 加載 DataBinding 布局 / 布局配置 ViewModel 對(duì)象 / 設(shè)置 LiveData 觀察者
在 該 Activity 中 , 需要完成三個(gè)任務(wù) :
- 加載 DataBinding 布局 , 需要獲取 DataBinding 布局對(duì)應(yīng)的 ViewDataBinding 類(lèi) , 該類(lèi)生成后的名稱(chēng)為 ActivityMainBinding , 這是根據(jù) activity_main.xml 布局文件名稱(chēng)生成的類(lèi) ;
- 為 DataBinding 布局 配置 ViewModel 實(shí)例對(duì)象 , 先獲取 ViewModel 實(shí)例 , 然后設(shè)置給 DataBinding 布局 ;
- 設(shè)置 LiveData 觀察者 , 在 ViewDataBinding 類(lèi)中 , 可以直接調(diào)用 調(diào)用的 ViewDataBinding#setLifecycleOwner 函數(shù) 將本 Activity 組件設(shè)置為 LiveData 的觀察者即可 ;
Activity 系統(tǒng)組件代碼 :
package kim.hsl.vld
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import kim.hsl.vld.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 1. 加載數(shù)據(jù)綁定布局
var activityMainBinding: ActivityMainBinding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
// 2. 獲取數(shù)據(jù)模型
var viewModel: MyViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application)).get(MyViewModel::class.java)
// 3. 向布局中設(shè)置數(shù)據(jù)模型對(duì)象
activityMainBinding.viewmodel = viewModel
// 4. 設(shè)置 LiveData 在 DataBinding 中觀察者生命周期所有者
activityMainBinding.lifecycleOwner = this
}
}
5、執(zhí)行結(jié)果
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-428474.html
代碼示例 :
- GitHub : https://github.com/han1202012/ViewModel_LiveData_DataBinding
- CSDN : https://download.csdn.net/download/han1202012/87736717
到了這里,關(guān)于【Jetpack】ViewModel + LiveData + DataBinding 綜合使用 ( 核心要點(diǎn)說(shuō)明 | 組合方式 | 代碼示例 )的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!