kyleg
02/05/2020, 4:03 PMclass MyFragment : ... {
@Inject lateinit var mViewModelFactory: ViewModelProvider.Factory
private val mViewModel by lazy {
ViewModelProviders
.of(requireActivity(), mViewModelFactory)
.get(MyViewModel::class.java) // MyViewModel extends ViewModel
}
}
Any idea how I might parametrize this into a base class to ideally get rid of ALL this boilerplate? I have
abstract class BaseFragment<VM: ViewModel>: ... {
abstract var mViewModelFactory: ViewModelProvider.Factory
private val mViewModel by lazy {
ViewModelProviders
.of(requireActivity(), mViewModelFactory)
.get(?????)
}
}
This wuold at least enable
class MyFragment<MyViewModel> {
@Inject lateinit var mViewModelFactory: ViewModelProvider.Factory
}
But I’m stuck here. I thought about making a lookup table to map fragment classes to viewmodel classes, but would like to avoid that if possible.
Thoughts? I doubt it can be done, but thought I’d ask here.KiranShny
02/06/2020, 3:14 PMabstract class BaseFragment<V : ViewModel, S : ViewState> : Fragment() {
@Inject
lateinit var factory: ViewModelFactory
abstract val clazz: Class<V>
val _state = PublishSubject.create<S>()
val state = _state.hide()
val compositeBag = CompositeDisposable()
val vm: V by lazy {
ViewModelProviders.of(this, factory).get(clazz)
}
override fun onDetach() {
_state.onComplete()
compositeBag.clear()
super.onDetach()
}
}
KiranShny
02/06/2020, 3:15 PMclass XXFragment : BaseFragment<XXViewModel, XXState>() {
override val clazz: Class<XXViewModel> = XXViewModel::class.java