View Model
- Model for your views such as Activity or Fragment.
- View Models are lifecycle aware.
- Data required for your screen is stored at one place i.e. ViewModel.
- It may involve formatting that data in a particular format, accumulating data, any logic in displaying this data in your Ul.
Dependency
- To Implement View Model We need to use its Dependency
// View Model Dependency implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
Implement View Model in Android Project
- To use viewModel we need to create class that inherits ViewModel Class
package com.example.androidarchitecture import androidx.lifecycle.ViewModel class MainViewModel : ViewModel() { }
Important Note:
- model classes are independent from view , There are primarily used to hold data.
- They Do not represent View Or How You Use data in View .
So Make Sure That , You Only Hold Data in ViewModel, Do Not Hold Any Reference to any particular View In it ( Because It Will cause Memory leak )
- To Use in Our Main Activity We Need to create instance of our ViewModal Class In Our MainActivity
// create instance private lateinit var viewModel: MainViewModel // Intialise inside onCreate viewModel = ViewModelProvider(this)[MainViewModel::class.java] // or viewModel = ViewModelProvider(this).get(MainViewModel::class.java) // both initialization method are same
- View Model is Life cycle aware so we need to define which activity lifecycle it need to observe
- so we have passed
this@MainActivityinsideViewModelProvider()constructor to refer to the current instance of activity
Example
- Our View Model class will hold data and its current state when changes are made to activity life cycle
- then we can access in our application using viewModel Object
MainViewModel.kt
package com.example.androidarchitecture import androidx.lifecycle.ViewModel class MainViewModel : ViewModel() { var count: Int = 0 fun increment() { count++ } }
MainActivity.kt
package com.example.androidarchitecture import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.ViewModelProvider import com.example.androidarchitecture.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { private val TAG: String = "====" private lateinit var viewModel: MainViewModel private val binding: ActivityMainBinding by lazy { ActivityMainBinding.inflate(layoutInflater) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(binding.root) viewModel = ViewModelProvider(this)[MainViewModel::class.java] binding.textView.text = viewModel.count.toString() binding.btnIncrement.setOnClickListener { viewModel.increment() binding.textView.text = viewModel.count.toString() } } }
View Model Factory
- so we use
ViewModelProvider()class to create viewModel object
- But problem is that we can not pass argument or value to create viewModel instance with our initial value
- Problem : Can not Initialize our viewModel object
Solution:
- we need to create our custom
ViewModelProviderclass that can provide initialized viewModel object
- For That We Will our class with
ViewModelProvider.Factoryclass and override its methods
package com.example.androidarchitecture import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider class MainViewModelProvider(val counter : Int) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { return MainViewModel(counter) as T } }
- Factory will take Data and create and return initialized viewModel Object
How to Use View Model Provider Factory
- Instead of creating viewModel object by Default Factory
viewModel = ViewModelProvider(this@MainActivity)[MainViewModel::class.java]
- We need to specify Our Custom
ViewModelProvider.Factoryclass object
- It will take Parameter that will be used to create viewModel Object with Initial Value.
viewModel = ViewModelProvider(this@MainActivity,MainViewModelProvider(10))[MainViewModel::class.java]