繁体   English   中英

Kotlin 不理解 ViewModelProviders.of(activity ?: fragment)

[英]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)
    }

有没有更好的方法来做到这一点?

是的,这是编译器歧义,因为您同时传递activitythis (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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM