Android ViewModelProviders.get(…)在基类中
我试图通过在抽象基类中移动一些ViewModel实例化来切割Dagger的一些样板文件,但找不到很好的方法。我的意图是从我的基本片段实例化我的所有ViewModels,以便它们可以被所有子片段使用,而不需要它们自己进行实例化。我的问题在于使用泛型(VM)检索ViewModel,特别是在这里:Android ViewModelProviders.get(…)在基类中,android,kotlin,dagger-2,Android,Kotlin,Dagger 2,我试图通过在抽象基类中移动一些ViewModel实例化来切割Dagger的一些样板文件,但找不到很好的方法。我的意图是从我的基本片段实例化我的所有ViewModels,以便它们可以被所有子片段使用,而不需要它们自己进行实例化。我的问题在于使用泛型(VM)检索ViewModel,特别是在这里:.get(ViewModel::class.java)。我还尝试了.get(VM::class.java)这是不允许的 BaseFragment abstract class BaseFragment<
.get(ViewModel::class.java)
。我还尝试了.get(VM::class.java)
这是不允许的
BaseFragment
abstract class BaseFragment<VM : ViewModel> : Fragment() {
@Inject lateinit var viewModelFactory: ViewModelProvider.Factory
lateinit var viewModel : VM
override fun onAttach(context: Context?) {
super.onAttach(context)
viewModel = ViewModelProviders.of(this, viewModelFactory).get(viewModel::class.java)
}
}
抽象类BaseFragment:Fragment(){
@注入lateinit var viewModelFactory:ViewModelProvider.Factory
lateinit var viewModel:VM
重写转速表(上下文:上下文?){
super.onAttach(上下文)
viewModel=ViewModelProviders.of(这是viewModelFactory).get(viewModel::class.java)
}
}
ViewModelProviders.get(…)方法签名
public <T extends ViewModel> T get(@NonNull Class<T> modelClass)
public T get(@NonNull Class-modelClass)
这可能吗?如果您有这样定义的
BaseFragment
:
public class BaseFragment<T extends ViewModel> extends Fragment {
@Inject
protected T viewModel;
}
在BaseFragment
的onActivityCreated
方法中,您可以添加
@Override
public void onActivityCreated(@Nullable final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ViewModelProvider.Factory viewModelFactory = ViewModelUtil.createFor(viewModel);
ViewModelProviders.of(this, viewModelFactory).get(viewModel.getClass());
}
这项技术的代码来自。我也遇到了同样的问题,但经过一点反思后修复了它;我真的不喜欢在Android上使用反射,但没有其他选择
private void initViewModel() {
final Type[] types = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments();
mViewModel = ViewModelProviders.of(this).get((Class<M>) types[0]);
}
private void initViewModel(){
最终类型[]类型=((ParameteredType)this.getClass().getGenericSuperclass()).getActualTypeArguments();
mViewModel=ViewModelProviders.of(this).get((Class)类型[0]);
}
希望这对某人有用 val viewModel:T由lazy创建{
val viewModel: T by lazy {
ViewModelProviders.of(this).get(getTClass())
}
//获取泛型T的实际类型
private fun getTClass(): Class<T> {
return (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<T>
}
ViewModelProviders.of(this.get)(getTClass())
}
//获取泛型T的实际类型
私有类():类{
返回(javaClass.genericSuperclass作为ParameterizedType)。actualTypeArguments[0]作为类
}
查看这篇博客文章,希望我在几天前找到它,这太棒了!非常感谢。我添加了一个答案,这样您就可以将问题标记为已回答。但这样,所有片段将具有与扩展相同片段相同的上下文,并且viewmodel中的值将永远有效。是这样吗?我有一个问题,如何避免这种情况。看起来不错,但插入的ViewModels在方向更改后不是同一个实例,因为它们每次都生成:(
val viewModel: T by lazy {
ViewModelProviders.of(this).get(getTClass())
}
//获取泛型T的实际类型
private fun getTClass(): Class<T> {
return (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<T>
}