ViewModel in Android Architecture Components
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 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.
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
Please Login to comment...