查看ViewModel的谷歌文档,他们展示了下面如何获取ViewModel的示例代码:
val model = ViewModelProviders.of(this).get(MyViewModel::class.java)
当使用最新的依赖项android.arch.lifecycle:extensions:1.1.1时,没有这样的类ViewModelProviders。
去查看ViewModelProviders的文档,我看到一条评论说:
这个类在API级别1.1.0中已弃用。使用ViewModelProvider。AndroidViewModelFactory
问题是,当尝试使用ViewModelProvider时。AndroidViewModelFactory,找不到一个等效的方法来获取ViewModel的实例。
我尝试做的事情:
ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(PlayerViewHolder::class.java)
因此,方法的名称创建,我得到一个新的实例的ViewModel每次我调用它,这不是我所追求的。
有什么想法是替换上面已弃用的代码?
//Activity ktx
implementation 'androidx.activity:activity-ktx:1.5.1'
//Fragment ktx
implementation 'androidx.fragment:fragment-ktx:1.5.1'
创建视图模型的最简单方法:
class MyViewModel() : ViewModel() {
}
class SomeActivity:AppCompatActivity(){
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_some)
}
}
带有构造函数参数的视图模型:
class MyViewModel(list:List<String>) : ViewModel() {
class Factory(list:List<String>) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return MyViewModel(list) as T
}
}
}
class SomeActivity:AppCompatActivity(){
private val viewModel: MyViewModel by viewModels(){
MyViewModel.Factory(listOf<String>("a"))}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
正如@FantasyFang在他的回答中提到的,使用生命周期的最新版本:lifecycle-extensions,目前是2.2.0-alpha03。所以你应该加入你的构建。Gradle文件如下行:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-alpha03'
对于那些使用Java的人来说,要解决这个问题,可以直接将这些参数传递给ViewModelProvider的构造函数:
MyViewModel viewModel = new ViewModelProvider(this, myViewModelFactory).get(MyViewModel.class);
或者如果你不使用工厂,简单地使用:
MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
没有传递给你工厂对象。
我使用生命周期扩展2.2.0版本:
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
它应该工作,使用ViewModelProvider构造函数。
// With ViewModelFactory
val viewModel = ViewModelProvider(this, YourViewModelFactory).get(YourViewModel::class.java)
//Without ViewModelFactory
val viewModel = ViewModelProvider(this).get(YourViewModel::class.java)
2020/5/15更新
我发现了另一种优雅的方式来实现这一点,Android KTX可以帮助
implementation "androidx.fragment:fragment-ktx:1.2.4"
val viewmodel: MYViewModel by viewModels()
val viewmodel: MYViewModel by viewModels { myFactory } //With factory
裁判:https://developer.android.com/reference/kotlin/androidx/fragment/app/package-summary #视图模型
2020/06/25:修正了委托的大小写
实际上,ViewModelProviders.of()方法在底层做什么?
@Deprecated
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment) {
return new ViewModelProvider(fragment);
}
它以Fragment作为参数,创建ViewModelProvider对象,并将片段直接传递给ViewModelProvider构造函数。
我们也可以用同样的方法。
例如:
OurViewModel mOurViewModel = ViewModelProviders.of(this).get(OurViewModel.class);
后:
OurViewModel mOurViewModel = new ViewModelProvider(this).get(OurViewModel.class);