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

时间:2018-10-15 07:27:43

标签: android kotlin android-viewmodel viewmodelproviders

Fragment内,我使用ViewModel初始化了ViewModelProviders。 我希望它采用Activity(如果不是null,否则为Fragment)。

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

使用提供的参数不能调用以下功能。

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

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

我现在必须使用

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

还有更好的方法吗?

3 个答案:

答案 0 :(得分:4)

是的,这是编译器含糊性,因为您同时传递了activitythis (fragment instance),并且在 ViewModelProviders中有不同的实现方式< / strong>。

另一种方法是通过使用如下的 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.
        }
    }
}

答案 1 :(得分:2)

除了Jeel的答案外,我建议,如果您通常需要使用此模式,则应在firebase deploy上定义扩展功能,以避免重复。例如:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main ()

{
  int x, i, c[101], mode;

  printf("please enter test scores between 0 and 100\n");

  i = 0;
  mode = 0; 

  while (i<=100) 
    {
      c[i]=0;
      i=i+1;
    }

  scanf("%d", &x);

  while ((x>=0) && (x<=100)) 
    {
      c[x]=c[x]+1;

      if (c[x]>=mode)
    {mode=x;}

      scanf("%d", &x);
    }

 printf("the mode is %d\n", mode);

}

从那里,在任何Fragment中,您都可以拨打以下电话之一:

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

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

这将避免获取提供程序的样板化过程,也将避免专门指定Java类。

答案 2 :(得分:0)

如果您使用的是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)