简体   繁体   English

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

[英]Kotlin does not understand ViewModelProviders.of(activity ?: fragment)

Inside my Fragment I initialize a ViewModel using ViewModelProviders .在我的Fragment我初始化ViewModel使用ViewModelProviders I want it to take its Activity if not null , otherwise itself ( Fragment ).如果不是null ,我希望它采用它的Activity ,否则它本身( Fragment )。

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

None of the following functions can be called with the arguments supplied.不能使用提供的参数调用以下函数。

  • of(Fragment) defined in androidx.lifecycle.ViewModelProviders of(Fragment) 在 androidx.lifecycle.ViewModelProviders 中定义
  • of(FragmentActivity) defined in androidx.lifecycle.ViewModelPro of(FragmentActivity) 在 androidx.lifecycle.ViewModelPro 中定义

It seems the language does not allow me to invoke conflicting method signatures (between of(Activity) and of(Fragment) . (It might be understandable, maybe the compiler has to reference only one method and cannot link to both on the same line.) Is that so?似乎该语言不允许我调用冲突的方法签名(在of(Activity)of(Fragment) 。(这可能可以理解,也许编译器只需要引用一个方法,而不能在同一行上链接到这两个方法。 )是这样吗?

I now have to use我现在必须使用

    activity?.let {
        ViewModelProviders.of(it).get(MainViewModel::class.java)
    } ?: run {
        ViewModelProviders.of(this).get(MainViewModel::class.java)
    }

Is there any better way of doing this?有没有更好的方法来做到这一点?

Yes, it's compiler ambiguity , because you're passing activity & this (fragment instance) at the same time which has different implementations in ViewModelProviders .是的,这是编译器歧义,因为您同时传递activitythis (fragment instance) ,它在ViewModelProviders有不同的实现。

Another approach to do this is by using when condition like below, (although your approach is also good) :另一种方法是使用如下所示的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.
        }
    }
}

if you are using androidx so should add two lines for lifecycle :如果您使用的是 androidx,那么应该为生命周期添加两行:

 def lifecycle_version = "2.2.0-rc02"
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"

and use it like this :并像这样使用它:

 val mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)

In addition to Jeel's answer, I'd recommend that if you commonly need to use this pattern, you should define an extension function on Fragment for it to avoid repetition.除了 Jeel 的回答之外,我建议如果您通常需要使用这种模式,您应该在Fragment为其定义一个扩展函数以避免重复。 For example:例如:

fun Fragment.getViewModelProvider() =
    activity?.let(ViewModelProviders::of) ?: ViewModelProviders.of(this)

inline fun <reified T : ViewModel> Fragment.getViewModel() = 
    getViewModelProvider().get(T::class.java)

From there, within any Fragment you can just call either:从那里,您可以在任何Fragment调用:

val viewModel: MainViewModel = getViewModel()
val viewModel = getViewModel<MainViewModel>()

It'll avoid both the boilerplate of fetching the provider as well as specifying the Java class specifically.它将避免获取提供者的样板以及专门指定 Java 类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ViewModelProviders.of(activity) 只接受片段或片段活动 - ViewModelProviders.of(activity) only accept fragment or fragmentactivity 我无法在 ViewModelProviders.of() function 中将片段作为参数 - I can't give fragment as argument inside ViewModelProviders.of() function 错误:找不到方法ViewModelProviders.of(Fragment,Factory)的合适方法 - error: no suitable method found for method ViewModelProviders.of(Fragment,Factory) ViewModelProviders.of(getActivity()) “无法解析(android.app.Activity)的方法” - ViewModelProviders.of(getActivity()) “Cannot resolve method of(android.app.Activity)” 当 ViewModelProviders.of() 被弃用时,如何在 Activity 和 Service 之间共享相同的 ViewModel? - How to share the same ViewModel between Activity and Service when ViewModelProviders.of() is deprecated? ViewModelProviders.of(FragmentActivity).get(ViewModel :: class.java)要求活动而不是get()调用中的viewmodel - ViewModelProviders.of(FragmentActivity).get(ViewModel::class.java) asking for activity instead of viewmodel in get() call 直接实例化ViewModels,而不使用ViewModelProviders.of方法 - Instantiate ViewModels directly, without making use of ViewModelProviders.of method 由于不推荐使用 ViewModelProviders.of(),我应该如何创建 ViewModel 的 object? - As ViewModelProviders.of() is deprecated, how should I create object of ViewModel? 如何在Non-FragmentActivity上使用ViewModelProviders.of()获取ViewModel? - How to fetch the ViewModel using ViewModelProviders.of() on non-FragmentActivity? Android Studio,AndroidX,ViewModelProviders.of(this)上的“无法解析方法。” - Android Studio, AndroidX, “Cannot resolve method..” on ViewModelProviders.of(this)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM