Kotlin不了解ViewModelProviders.of(活动?:片段)

shk*_*der 5 android kotlin android-viewmodel viewmodelproviders

在我内部,我Fragment初始化一个ViewModelusing ViewModelProviders。我希望它采用Activityif否则null,否则采用(Fragment)。

private val viewModel: MainViewModel by lazy {
    ViewModelProviders.of(activity ?: this).get(MainViewModel::class.java)
}
Run Code Online (Sandbox Code Playgroud)

使用提供的参数不能调用以下任何函数。

  • 在androidx.lifecycle.ViewModelProviders中定义的(片段)
  • 在androidx.lifecycle.ViewModelPro中定义的(FragmentActivity)

似乎该语言不允许我调用冲突的方法签名(在of(Activity)和之间of(Fragment)。(这是可以理解的,也许编译器必须仅引用一个方法并且不能在同一行上链接到这两个方法。)是吗?

我现在必须使用

    activity?.let {
        ViewModelProviders.of(it).get(MainViewModel::class.java)
    } ?: run {
        ViewModelProviders.of(this).get(MainViewModel::class.java)
    }
Run Code Online (Sandbox Code Playgroud)

有什么更好的方法吗?

Jee*_*ede 6

是的,这是编译器的歧义,因为您要同时传递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.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


san*_*adi 5

如果您使用的是 androidx,那么应该为生命周期添加两行:

 def lifecycle_version = "2.2.0-rc02"
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

 val mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)