Build MVVM Application with Kotlin — Part 4: ViewModel

ditclear
3 min readJan 29, 2020

This article will introduce the use of Google’s recommended architecture component ViewModel.

Why is there a ViewModel?

why? Seeing the name ViewModel is believed to be linked to the VM in the MVVM architecture.

But in my opinion, these two are not the same. If you want to implement an MVVM architecture app, following the previous three articles is enough.

And I speculate that Google may call it ViewModel for two reasons:

  1. The ViewModel architecture components serve the VM layer.
  2. It is easy to think of the MVVM architecture, which means that Google recommends that Android engineers use the MVVM architecture rather than a complicated MVP.

Of course these are digressions. Now that you can build MVVM applications without using ViewModel, what does ViewModel do?

The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.

Quick start

First we need to add the corresponding dependencies in app / build.gradle.

//ViewModel
implementation "android.arch.lifecycle:extensions:1.1.1"
implementation "android.arch.lifecycle:viewmodel:1.1.1"
kapt "android.arch.lifecycle:compiler:1.1.1"

Then, let your VM layer inherit the ViewModel class provided by the ViewModel component. If you need to use the Application context, then inherit the AndroidViewModel class.

class PaoViewModel constructor(private val repo: PaoRepo) :ViewModel(){
//...
}

In the PaoActivity of the View layer, you need to modify it now.

class PaoActivity : AppCompatActivity() {

lateinit var mBinding : PaoActivityBinding

lateinit var mViewModel : PaoViewModel

lateinit var factory: ViewModelProvider.Factory

override fun onCreate(savedInstanceState: Bundle?) {
//....
mViewModel=ViewModelProviders.of(this,factory).get(PaoViewModel::class.java)
//...
}

}

Here are two concepts ViewModelProvider.Factory and ViewModelProviders. Before continuing, we need to understand how to build our own ViewModelProvider.Factory.

ViewModelProvider.Factory

When you see this name, you naturally think of the factory pattern. Here we provide the mViewModel instance we need. Of course, the ViewModel is not so magical and will not help us automatically generate it, so we need to implement the ViewModelProvider.Factory we need.

class PaoViewModelFactory : ViewModelProvider.Factory{
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
//return T
}
}

So how do you create a concrete instance? You can create new dependencies one by one here.

class PaoViewModelFactory  constructor(): ViewModelProvider.Factory{
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
//////model
val remote=Retrofit.Builder()
.baseUrl(Constants.HOST_API)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(PaoService::class.java)
val local=AppDatabase.getInstance(applicationContext).paoDao()
val repo = PaoRepo(remote, local)
/////ViewModel
mViewMode= PaoViewModel(repo)
if (modelClass.isInstance(mViewMode)){
return mViewMode as T
}else{
throw IllegalArgumentException("unknown model class $modelClass")
}
}

}

You’re done. Now that our ViewModel has the ability to rebuild the screen rotation activity, the data in the ViewModel is still valid.

End

The github address of this project:

More examples can be viewed:

The only regret is that we need to write too much templated code in order to provide a ViewModel.

//////model
val remote=Retrofit.Builder()
.baseUrl(Constants.HOST_API)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(PaoService::class.java)
val local=AppDatabase.getInstance(applicationContext).paoDao()
val repo = PaoRepo(remote, local)
/////ViewModel
mViewMode= PaoViewModel(repo)

It would be great if you could not write.

of course can.

So the content of the next article is to rely on the retrieval container—Koin, to achieve the rapid injection of ViewModel.

--

--