我想拥有一个基础活动类,该类负责一些初始化工作,我开始像这样定义它。
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”用作类型化参数。改用课程
我应该如何解决此问题,我想在其中将ViewModel的类型定义为BaseActivity的类型化参数。
该如何实例化它?
答案 0 :(得分:1)
一种解决方案是拥有这样的东西
abstract val viewModelClass: Class<VIEW_MODEL>
我真的很想不要这样的东西
答案 1 :(得分:0)
@svkaka已经提到了一种解决方案。创建一个抽象方法,并用您的ViewModel类覆盖它:
protected abstract fun getViewModel(): Class<M>
用
替换行viewmodel = ViewModelProviders.of(this).get(getViewModel())
希望它会起作用。
答案 2 :(得分:0)
第一种方法在基本活动中创建abstarct方法。这样,您必须在所有活动中覆盖abstarct方法。
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()
}
}
当您在活动中覆盖此方法时
override fun getViewModel(): MyProfileViewModel {
mMyProfileViewModel = ViewModelProviders.of(this, mViewModelFactory).get(MyProfileViewModel::class.java)
return mMyProfileViewModel
}
第二种方法
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>
}
}