在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)
}
还有更好的方法吗?
答案 0 :(得分:4)
是的,这是编译器含糊性,因为您同时传递了activity
和this (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)