ViewModel in Android

Overview

ViewModel is lifecycle aware. It is a Model for your views like Activities and Fragments. Data require for your screen is stored at one place i.e. ViewModel. The data may involve the information to format a data, or it could be an accumulated data such as scores earned by a user or it could be a business logic that you display onto the screen. ViewModel is used only to store data, it doesn't care how you are using this data.

Code without ViewModel

 class MainActivity : AppCompatActivity() {
private var counter: Int = 0;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setContent()
}

/* Do not declare the fun as private because this function is declared in the xml file of the activity*/
fun increment(view: View?) {
counter++
setContent()
}

private fun setContent() {
tvCounter.text = counter.toString()
}

}

Steps to Follow

  • Add the required dependency in build.gradle (Module) file.
 def lifecycle_version = "2.3.0"
def arch_version = "2.1.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Annotation processor
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional - helpers for implementing LifecycleOwner in a Service
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
// optional - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"
// optional - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$arch_version"
  • Create a class and extend it with ViewModel() class. Write the logic in this class.
 class MainViewModel : ViewModel() {
/* Do not make the variable private because you have to use this variable in MainActivity */
var counter: Int = 0;

/* Do not make the function private because you have to use this function in MainActivity */
fun increment() {
counter++
}
}
  • Create an instance of ViewModel in MainActvity (or the Activity where you want to display the data) and use its instance to run the method defined in ViewModel class and / or use its instance to display the properties defined in ViewModel
 class MainActivity : AppCompatActivity() {
private lateinit var mainViewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
setContent()
}

/* Do not declare the fun as private because this function is declared in the xml file of MainActivity*/
fun increment(view: View?) {
mainViewModel.increment()
setContent()
}

private fun setContent() {
tvCounter.text = mainViewModel.counter.toString()
}

}

Do's and Dont's

  • Do not hold a reference of View in ViewModel because such reference could improve the risk of memory leak.

Reference



Comments

Popular posts from this blog

SSLSocketFactory in Android

DataBinding in Android

Convert Password Characters into a placeholder character.