如何在BaseActivty类中具有通用ViewModel [英] How to have generic ViewModel in BaseActivty class

查看:252
本文介绍了如何在BaseActivty类中具有通用ViewModel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想拥有一个基础活动类,该类负责一些初始化工作,我开始像这样定义它.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆