[英]ViewModelProviders.of(activity) only accept fragment or fragmentactivity
[英]Kotlin does not understand ViewModelProviders.of(activity ?: fragment)
在我的Fragment
我初始化ViewModel
使用ViewModelProviders
。 如果不是null
,我希望它采用它的Activity
,否则它本身( Fragment
)。
private val viewModel: MainViewModel by lazy {
ViewModelProviders.of(activity ?: this).get(MainViewModel::class.java)
}
不能使用提供的参数调用以下函数。
- of(Fragment) 在 androidx.lifecycle.ViewModelProviders 中定义
- of(FragmentActivity) 在 androidx.lifecycle.ViewModelPro 中定义
似乎该语言不允许我调用冲突的方法签名(在of(Activity)
和of(Fragment)
。(这可能可以理解,也许编译器只需要引用一个方法,而不能在同一行上链接到这两个方法。 )是这样吗?
我现在必须使用
activity?.let {
ViewModelProviders.of(it).get(MainViewModel::class.java)
} ?: run {
ViewModelProviders.of(this).get(MainViewModel::class.java)
}
有没有更好的方法来做到这一点?
是的,这是编译器歧义,因为您同时传递activity
和this (fragment instance)
,它在ViewModelProviders
有不同的实现。
另一种方法是使用如下所示的when
条件(尽管您的方法也不错) :
private val viewModel: MainViewModel by lazy {
return@lazy when {
activity != null -> {
ViewModelProviders.of(activity as FragmentActivity).get(MainViewModel::class.java) // you can either pass activity object
}
else -> {
ViewModelProviders.of(this).get(MainViewModel::class.java) // or pass fragment object, both are not possible at same time.
}
}
}
如果您使用的是 androidx,那么应该为生命周期添加两行:
def lifecycle_version = "2.2.0-rc02"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
并像这样使用它:
val mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
除了 Jeel 的回答之外,我建议如果您通常需要使用这种模式,您应该在Fragment
为其定义一个扩展函数以避免重复。 例如:
fun Fragment.getViewModelProvider() =
activity?.let(ViewModelProviders::of) ?: ViewModelProviders.of(this)
inline fun <reified T : ViewModel> Fragment.getViewModel() =
getViewModelProvider().get(T::class.java)
从那里,您可以在任何Fragment
调用:
val viewModel: MainViewModel = getViewModel()
val viewModel = getViewModel<MainViewModel>()
它将避免获取提供者的样板以及专门指定 Java 类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.