建立含依附元件的 ViewModel (Android Jetpack 的一部分)。
遵循依附元件插入最佳做法,ViewModel 可將依附元件做為其建構函式中的參數。這些類型主要來自網域或資料層。由於架構提供 ViewModel,因此必須採用特殊的機制來建立其執行個體。這種機制即為 ViewModelProvider.Factory 介面。只有實作這個介面才能在適當範圍內將 ViewModel 執行個體化。
ViewModels 搭配 CreationExtras
如果 ViewModel 類別在其建構函式中接收依附元件,請提供實作 ViewModelProvider.Factory 介面的工廠。覆寫 create(Class<T>, CreationExtras) 函式來提供 ViewModel 的新執行個體。
CreationExtras 允許您存取有助於對 ViewModel 執行個體化的相關資訊。下面是可透過額外項目存取的金鑰清單:
| 金鑰 | 功能 |
|---|---|
ViewModelProvider.NewInstanceFactory.VIEW_MODEL_KEY |
提供傳遞至 ViewModelProvider.get() 的自訂金鑰存取權。 |
ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY |
提供 Application 類別的執行個體存取權。 |
SavedStateHandleSupport.DEFAULT_ARGS_KEY |
提供應當用於建構 SavedStateHandle 的引數套件存取權。 |
SavedStateHandleSupport.SAVED_STATE_REGISTRY_OWNER_KEY |
提供用於建構 ViewModel 的 SavedStateRegistryOwner 存取權。 |
SavedStateHandleSupport.VIEW_MODEL_STORE_OWNER_KEY |
提供用於建構 ViewModel 的 ViewModelStoreOwner 存取權。 |
如要建立新的 SavedStateHandle 執行個體,請使用 CreationExtras.createSavedStateHandle() 函式,並將其傳遞至 ViewModel。
搭配 APPLICATION_KEY 的 CreationExtras
以下範例說明如何提供 ViewModel 執行個體,該執行個體以範圍限定為 Application 類別和 SavedStateHandle 的存放區做為依附元件:
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.createSavedStateHandle
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
class MyViewModel(
private val myRepository: MyRepository,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
// ViewModel logic
// ...
// Define ViewModel factory in a companion object
companion object {
val Factory: ViewModelProvider.Factory = viewModelFactory {
initializer {
val savedStateHandle = createSavedStateHandle()
val myRepository = (this[APPLICATION_KEY] as MyApplication).myRepository
MyViewModel(
myRepository = myRepository,
savedStateHandle = savedStateHandle
)
}
}
}
}
之後您就可以在擷取 ViewModel 執行個體時使用這個工廠:
import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun MyScreen(
modifier: Modifier = Modifier,
viewModel: MyViewModel = viewModel(factory = MyViewModel.Factory)
) {
// ...
}
以 CreationExtras 形式傳遞自訂參數
您可以透過建立自訂鍵,將依附元件傳遞至 ViewModel。CreationExtras如果 ViewModel 依附的物件無法透過 Application 類別和 APPLICATION_KEY 存取,這個方法就很有用。舉例來說,如果 ViewModel 是在 Kotlin 多平台模組中建立,因此無法存取 Android 依附元件,就會發生這種情況。
在本範例中,ViewModel 會定義自訂鍵,並在 ViewModelProvider.Factory 中使用。
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
class MyViewModel(
private val myRepository: MyRepository,
) : ViewModel() {
// ViewModel logic
// Define ViewModel factory in a companion object
companion object {
// Define a custom key using the factory function
val MY_REPOSITORY_KEY = CreationExtras.Key<MyRepository>()
val Factory: ViewModelProvider.Factory = viewModelFactory {
initializer {
// Get the dependency in your factory
val myRepository = this[MY_REPOSITORY_KEY] as MyRepository
MyViewModel(
myRepository = myRepository,
)
}
}
}
}
您可以在可組合函式中,直接使用 CreationExtras.Key 例項化 ViewModel。
import androidx.lifecycle.viewmodel.MutableCreationExtras
import androidx.lifecycle.viewmodel.compose.viewModel
// ...
@Composable
fun MyApp(myRepository: MyRepository) {
val extras = MutableCreationExtras().apply {
set(MyViewModel.MY_REPOSITORY_KEY, myRepository)
}
val viewModel: MyViewModel = viewModel(
factory = MyViewModel.Factory,
extras = extras,
)
}
其他資源
如要進一步瞭解 ViewModel 和依附元件,請參閱下列其他資源:
說明文件
Views content
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- ViewModel 的已儲存狀態模組
- 儲存 UI 狀態