Michael Pohl
04/09/2020, 6:01 PMabstract class ViewModelFragment<VM : BaseViewModel>(@LayoutRes val layout: Int, private val viewModelClass: KClass<VM>) :
BaseFragment() {
open lateinit var viewModel: VM
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
viewModel = getViewModel(viewModelClass)
return inflater.inflate(layout, container, false)
}
}
The idea was to remove as much boilerplate noise in the fragment classes as possible. This project also used Koin
for DI, this class uses Koin's
getViewModel()
to set the viewModel.
What I don’t like about this approach is that subclasses of this have a constructor that looks like this:
class AudioPlayerFragment : ViewModelFragment<AudioPlayerViewModel>(R.layout.fragment_audio_player, AudioPlayerViewModel::class)
As you can see, for this to work, you need a type annotation and still have to hand in the KClass type, which is just ugly.
So I’m wondering if there is any way to get this to just look like this:
class MyFragment<MyViewModel> : ViewModelFragment(myLayout) {}
I understand that there is a limitation as to what Kotlin can do with generics and that I’m basically looking for what `reified`functions can do, but on a class, and that that’s no new question. I was hoping to find a solution like this here: https://stackoverflow.com/a/48398303/8746644
But I can’t figure out a way that would work with Fragments and sub classes . I could also see writing a custom getViewModel
function to deal with the type, but I don’t know how. Does anybody have a suggestion how I could achieve what I want in a reasonable way?wasyl
04/10/2020, 8:03 AMMichael Pohl
04/10/2020, 8:34 AM