如何在BaseActivty类中具有通用ViewModel [英] How to have generic ViewModel in BaseActivty class
问题描述
我想拥有一个基础活动类,该类负责一些初始化工作,我开始像这样定义它.
I want to have a base activity class that takes care of some initialization I started defining it like this.
abstract class BaseActivity<VIEW_MODEL : ViewModel, BINDING : ViewDataBinding> :
AppCompatActivity() {
lateinit var viewmodel: VIEW_MODEL
lateinit var binding: BINDING
lateinit var glide: RequestManager
@get:LayoutRes
abstract val layoutResource: Int
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, layoutResource)
viewmodel = ViewModelProviders.of(this).get(VIEW_MODEL::class.java)
^^^^^^^^^^^^^^^^^
this is causing error
}
}
但是我收到此错误
不能使用'VIEW_MODEL'作为化类型参数.改用课程
Cannot use 'VIEW_MODEL' as reified type parameter. Use a class instead
我应该如何解决此问题,我想在其中将ViewModel的类型定义为BaseActivity的类型化参数.
How should I solve this problem, where I want to define the type of ViewModel as typed parameter of BaseActivity.
该如何实例化它?
推荐答案
第一种方法在基本活动中创建abstarct方法.这样,您必须在所有活动中覆盖abstarct方法.
1st way Make abstarct method in Base Activity.In this way you have to override abstarct method in all activity.
abstract class BaseActivity< ViewModel : BaseViewModel,Binding : ViewDataBinding> : AppCompatActivity(){
protected lateinit var binding: Binding
private var mViewModel: V? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
performViewModelBinding()
}
@LayoutRes
abstract fun getLayoutResId(): Int
abstract fun getViewModel(): ViewModel
private fun performViewModelBinding() {
binding = DataBindingUtil.setContentView(this, getLayoutResId())
this.mViewModel = mViewModel ?: getViewModel()
binding.setVariable(BR.viewModel, mViewModel)
binding.executePendingBindings()
}
}
当您在活动中覆盖此方法时
And when you override this method in activity
override fun getViewModel(): MyProfileViewModel {
mMyProfileViewModel = ViewModelProviders.of(this, mViewModelFactory).get(MyProfileViewModel::class.java)
return mMyProfileViewModel
}
第二种方法
2nd way you can do this
abstract class BaseActivity<VIEW_MODEL : ViewModel, BINDING : ViewDataBinding> :
AppCompatActivity() {
lateinit var viewmodel: VIEW_MODEL
lateinit var binding: BINDING
lateinit var glide: RequestManager
@get:LayoutRes
abstract val layoutResource: Int
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, layoutResource)
viewmodel = ViewModelProviders.of(this).get(getViewModelClass())
}
private fun getViewModelClass(): Class<VIEW_MODEL> {
val type = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] // index of 0 means first argument of BaseActivity class param
return type as Class<VIEW_MODEL>
}
}
这篇关于如何在BaseActivty类中具有通用ViewModel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!