一、概念
二、使用
ViewModel 生命周期长于 Activity/Fragment,如果直接 new 出来就失去了意义。
2.1 创建ViewModel
//无参
class MainViewModel : ViewModel() {}
//有参
class MainViewModel(mainRepository: MainRepository) : ViewModel() {}
class MainViewModelFactory(private val mainRepository: MainRepository) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return MainViewModel(mainRepository) as T
}
}
2.2 View中使用
不推荐
//写法一:延迟初始化(因为不能在onCreate之前调用)
lateinit var viewmodel: MainViewModel
onCreate{
ViewModelProvider(this)[MainViewModel::class.java] //无参
MainViewModelFactory(MainRepository()).create(MainViewModel::class.java) //有参
}
//写法二:懒加载(可以一次性都写在类属性位置)
val viewmodel by lazy {
ViewModelProvider(this)[MainViewModel::class.java] //无参
MainViewModelFactory(MainRepository()).create(MainViewModel::class.java) //有参
}
推荐(不能用的话需要导包)
implementation "androidx.activity:activity-ktx:1.6.1"
val viewModel by viewModels<MainViewModel>() //无参
val viewModel by viewModels<MainViewModel> { MainViewModelFactory(MainRepository()) } //有参
2.3 Compose中使用
- 仅用于最顶层屏幕级组合函数(离 Activity/Fragment 中 setContent() 最近的那个)。
- 遵循唯一可信数据源,ViewModel将状态传递给子组合项,子组合项将事件上抛给父组合项,不要直接将 ViewModel 向下传递给子组合项。
@Composable
fun DemoScreen(viewModel: DemoViewModel = viewModel()) {
Demo(dataState = viewModel.dataState) {
viewModel.buttonClicked()
}
}
@Composable
fun Demo(
dataState: String,
onClick: () -> Unit,
) {
Button(onClick = onClick) {
Text(text = dataState)
}
}
class DemoViewModel : ViewModel() {
var dataState by mutableStateOf("")
private set
fun buttonClicked() { }
}