Inside my Fragment
I initialize a ViewModel
using ViewModelProviders
.
I want it to take its Activity
if not null
, otherwise itself (Fragment
).
private val viewModel: MainViewModel by lazy {
ViewModelProviders.of(activity ?: this).get(MainViewModel::class.java)
}
None of the following functions can be called with the arguments supplied.
- of(Fragment) defined in androidx.lifecycle.ViewModelProviders
- of(FragmentActivity) defined in androidx.lifecycle.ViewModelPro
It seems the language does not allow me to invoke conflicting method signatures (between of(Activity)
and of(Fragment)
. (It might be understandable, maybe the compiler has to reference only one method and cannot link to both on the same line.) Is that so?
I now have to use
activity?.let {
ViewModelProviders.of(it).get(MainViewModel::class.java)
} ?: run {
ViewModelProviders.of(this).get(MainViewModel::class.java)
}
Is there any better way of doing this?
Yes, it's compiler ambiguity, because you're passing activity
& this (fragment instance)
at the same time which has different implementations in ViewModelProviders
.
Another approach to do this is by using when
condition like below, (although your approach is also good):
private val viewModel: MainViewModel by lazy {
return@lazy when {
activity != null -> {
ViewModelProviders.of(activity as FragmentActivity).get(MainViewModel::class.java) // you can either pass activity object
}
else -> {
ViewModelProviders.of(this).get(MainViewModel::class.java) // or pass fragment object, both are not possible at same time.
}
}
}