Open In App

ViewModel in Android Architecture Components

Last Updated : 23 Mar, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

ViewModel is part of the android architecture component. Android architecture components are the components that are used to build robust, clean, and scalable apps. Android architecture components hold some classes to manage UI components and Data persistence. The ViewModel class is designed to store and manage UI-related data in a lifecycle-conscious way. ViewModel classes are used to store the data even the configuration changes like rotating screen. ViewModel is one of the most critical class of the Android Jetpack Architecture Component that support data for UI components. Its purpose is to hold and manage the UI-related data. Moreover, its main function is to maintain the integrity and allows data to service during configuration changes like screen rotations. Any kind of configuration change in Android devices tends to recreate the whole activity of the application. It means the data will be lost if it has been not saved and restored properly from the activity which was destroyed. To avoid these issues, it is recommended to store all UI data in the ViewModel instead of an activity. 

An activity must extend the ViewModel class to create a view model:

class MainActivityViewModel : ViewModel() {

………

……..

}

Implement ViewModel in Android App

Android Architecture Components provides the ViewModel helper class for the UI controller that is responsible for preparing data for the UI. ViewModel objects are automatically retained during configuration changes we will see that in the below example. Now let’s get into the code,

Step 1: Add these dependencies in the build.gradle file

def lifecycle_version = “2.3.0”

// ViewModel

implementation “androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version”

implementation “androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version”

implementation “androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version”

implementation “androidx.core:core-ktx:1.3.2”

Also, add the following dependency to the build.gradle(Module:app) file. We are adding these two dependencies because to avoid using findViewById() in our MainActivity.kt file. Try this out otherwise use the normal way like findViewById().

apply plugin: ‘kotlin-android’

apply plugin: ‘kotlin-android-extensions’

Below codes are without using ViewModel

Step 2: Working with the activity_main.xml file

Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file.

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
  
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.369" />
  
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:text="Click"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView"
        app:layout_constraintVertical_bias="0.0" />
  
</androidx.constraintlayout.widget.ConstraintLayout>


Step 3: Working with the MainActivity.kt file

Go to the MainActivity.kt file and refer to the following code. Below is the code for the MainActivity.kt file. 

Kotlin




import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
  
class MainActivity : AppCompatActivity() {
      
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
  
        var number = 0
  
        textView.text = number.toString()
  
        button.setOnClickListener {
            number++
            textView.text = number.toString()
        }
  
    }
}


Output:

Now just click on the button 3 to 4 times you will see the incremented number on the screen. Now just try to rotate your emulator or device.

You will see the number becomes 0, the question is why? How it erases the value by rotating the screen. Ok to get the answer we have to get some knowledge about the Lifecycle of a ViewModel.

Lifecycle of a ViewModel

In the above image when our activity created, the system calls the onCreate() after that onStart() then onResume() but when we rotate the screen our activity is destroyed and after rotation again system calls onCreate() and other functions one after another. As our activity destroyed our activity data has also vanished.

To overcome this problem we use ViewModels which holds the data even after configuration changes like the rotation of the screen. The above image is showing the ViewModel scope, even with any configuration changes the data is persistent. You usually request a ViewModel for the first time when the system calls an activity object’s onCreate() method. The system may call onCreate() several times throughout the life of an activity, such as when a device screen is rotated. The ViewModel exists from when you first request a ViewModel until the activity is finished and destroyed.

Example with ViewModel

Step 1: Create a Kotlin class file MainActivityViewModel.kt. Our MainActivity class file extends the ViewModel class.

Refer to this article: How to Create Classes in Android Studio?

Kotlin




import androidx.lifecycle.ViewModel
  
class MainActivityViewModel : ViewModel() {
    
    var number = 0
      
    fun addOne() {
        number++
    }
}


Step 2: Working with the MainActivity.kt file

Go to the MainActivity.kt file and update the following code. Below is the code for the MainActivity.kt file. Comments are added inside the code to understand the code in more detail.

Kotlin




import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import kotlinx.android.synthetic.main.activity_main.*
  
class MainActivity : AppCompatActivity() {
      
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
  
        // view model instance
        var viewModel: MainActivityViewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)
  
        // setting text view
        textView.text = viewModel.number.toString()
  
        //handling button click event
        button.setOnClickListener {
            viewModel.addOne()
            textView.text = viewModel.number.toString()
        }
    }
}


Output:

Even after rotating our screen, we get the same value. So that’s it, this is the basic of ViewModel there are many other advanced things of view model we will cover later.

Advantages of ViewModel Component

  • Helps in data management during configuration changes
  • Reduce UI bugs and crashes
  • Best practice for software design


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads