I am trying to implement the example on https://developer.android.com/jetpack/docs/guide. This explains how tan android app should be structured.
When I use the same code, I get following error.
java.lang.Class<com.example.UserProfileViewModel> has no zero argument constructor
I could figure out that this error has something to do with
viewModel = ViewModelProviders.of(this).get(UserProfileViewModel.class);
When I write a default zero input constructor for ViewModel I get the following error.
Attempt to invoke virtual method 'void android.arch.lifecycle.LiveData.observe(android.arch.lifecycle.LifecycleOwner, android.arch.lifecycle.Observer)' on a null object reference
I can not figure out the reason for this error and how to solve it.
If you want to provide viewmodel with constructor as a dependency in your Fragment, there is a different method for it,
Lets suppose you have a viewmodel class as belows,
class SampleViewmModel(dataManager:DataManager):ViewModel(){
//some logic
}
Then you will need to create a factory class to support above viewmodel like below,
class SampleFactory @Inject constructor(var dataManager:DataManager): ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(SampleViewModel::class)) {
return SampleViewModel(dataManager) as T
}
throw IllegalStateException()
}
}
Now in your module class, you can inject above classes as below, (Note-Datamanager class is injectible)
//Provide Factory
@Provides
fun provideFactory(dataManager:DataManager): SampleFactory {
return SampleFactory(dataManager)
}
//Provide actual viewmodel
@Provides
fun provideViewModel(sampleFactory: SampleFactory): SampleViewModel {
return ViewModelProviders.of(fragment, sampleFactory)[SampleViewModel::class]
}
No in your Fragment, you can inject your viewmodel just like any other dependency,
@Injetct
lateinit viewModel:SampleViewModel