Wallace Baldenebre
Wallace Baldenebre

Reputation: 90

Koin and Kotlin: Can't use T as reified parameter

I need to use tha class viewmodel() (from Koin) in a generic type T, but it returns to me an error:

Cannot use T as reified type parameter. Use Class instead.

Missing setValue(BaseViewModelActivity, KProperty<*>, T), method on delegate of type Lazy

What I've tried until now and my current code:

class ActivityDetailActivity : BaseViewModelActivity<ActivityDetailViewModel>() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_detail, ActivityDetailViewModel::class.java)
    }
}
open class BaseViewModel : ViewModel() { }
abstract class BaseViewModelActivity<T: BaseViewModel> : BaseActivity() {
    protected var viewModel: T by viewModel()

    protected open fun setContentView(layoutResID: Int, vm: Class<T>) {
        super.setContentView(layoutResID)
        setViewModel(vm)
    }

    private fun setViewModel(vm: Class<T>) {
        viewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(vm)
        viewModel.navigateTo.observeNonNull(this) {
            super.navigateTo(it)
        }
    }
}

The version of the Koin is the last: 2.+

Upvotes: 1

Views: 2317

Answers (2)

Akshay Raiyani
Akshay Raiyani

Reputation: 1333

How I set my BaseViewmodel and BaseActivity

abstract class BaseActivity<Binding : ViewDataBinding, ViewModel : BaseViewModel> : AppCompatActivity() {
protected lateinit var bindObject: Binding
protected abstract val mViewModel: ViewModel
abstract fun getLayoutResId(): Int

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(getLayoutResId())
    performViewModelBinding()
    }
}

BaseViewModel like this

open class BaseViewModel : ViewModel(), KoinComponent {}

I am using it like this

class SplashActivity : BaseActivity<ActivitySplashBinding, SplashViewModel>() {
override val mViewModel: SplashViewModel by currentScope.inject()

override fun getLayoutResId(): Int {
    return R.layout.activity_splash
}}

Upvotes: 0

user10350526
user10350526

Reputation: 186

Change

protected var viewModel: T by viewModel()

to

protected lateinit var viewModel: T

You cannot use the viewModels delegate in this case because it requires a reified type parameter, but T is a class type parameter which cannot be reified.

Instead, you initialize your viewModel to the appropriate type in setViewModel.

Upvotes: 1

Related Questions