ViewModel in Android
useful video & blogs :
https://www.youtube.com/watch?v=i22jxmIh_EE&t=10s
https://www.journaldev.com/21168/android-livedata
To use architecture components , you need to add the dependencies for them.
For ViewModel & LiveData add this :
implementation "androidx.lifecycle:lifecycle-viewmodel:2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata:2.2.0"
link for dependency - https://developer.android.com/jetpack/androidx/releases/lifecycle
---------------------------------------------------------------------------------------------------
ViewModel is used to manage UI related things like maintaing the state and data of the UI , so that it can survive config changes.
For small Data (under 100KB ) , we can use "onSaveInstance" , but for large amount of data , we need to use ViewModel.
Viewmodel's Scope is present throughout the app lifrcycle & is destroyed only when the UI gets completely destroyed i.e Viewmodel can survive configuration changes.
------------------------------------------------------------------------------------------
IN JAVA & KOTLIN
Simple ViewModel in Kotlin
MainActivity.kt
package com.deepesh.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.lifecycle.ViewModelProvider
import kotlin.concurrent.thread
class MainActivity : AppCompatActivity() {
// Our Viewmodel class which will pass us data.
lateinit var myviewmodel: MyViewModel
lateinit var textview: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//IMPORTANT.
myviewmodel = ViewModelProvider(this).get(MyViewModel::class.java)
textview = findViewById(R.id.textview1)
// Since Viewmodel class survives config changes
// we can fetch the data intact during onCreate()
// and maintain the state.
thread {
textview.text = myviewmodel.get_score()
Log.d("TAG", "Running on : ${Thread.currentThread().name} ")
}
}
fun add(view: View) {
myviewmodel.increment_score()
textview.setText(myviewmodel.get_score())
}
}
MyViewModel.kt
package com.deepesh.myapplication
import androidx.lifecycle.ViewModel
class MyViewModel : ViewModel() {
var score :Int =0
fun increment_score(){
score+=1
}
fun get_score():String{
return score.toString()
}
fun reset_score(){
if (score!=0){
score=0
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="140dp"
android:text="Hello World!"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="46dp"
android:layout_marginEnd="26dp"
android:onClick="add"
android:text="add"
app:layout_constraintEnd_toEndOf="@+id/textview1"
app:layout_constraintTop_toBottomOf="@+id/textview1" />
</androidx.constraintlayout.widget.ConstraintLayout>
--------------------------------------------------------------------------------------------
Simple ViewModel in JAVA
MainActivity.java
package com.deepesh.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView score_textview;
MyViewModel myviewmodel;
Button add_button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
score_textview=findViewById(R.id.score_textview);
add_button=findViewById(R.id.add_button);
add_button.setOnClickListener(listener);
// IMPORTANT///
myviewmodel= new ViewModelProvider(this).get(MyViewModel.class);
score_textview.setText(String.valueOf(myviewmodel.get_Score()));
}
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
myviewmodel.increment_score();
score_textview.setText(String.valueOf(myviewmodel.get_Score()));
}
};
}
MyViewModel.java
package com.deepesh.myapplication;
import androidx.lifecycle.ViewModel;
public class MyViewModel extends ViewModel {
int score=0;
int get_Score(){
return score;
}
void increment_score(){
score++;
}
}
EXAMPLE 2 :
package com.deepesh.exampleapp4;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView textView;
MyViewModel myViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
textView = findViewById(R.id.score_textview);
textView.setText(String.valueOf(myViewModel.getScore()));
}
// User clicks the button
public void IncrementSCore(View view) {
myViewModel.incrementScore();
textView.setText(String.valueOf(myViewModel.getScore()));
}
// ViewModel Class
public static class MyViewModel extends ViewModel{
int score;
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public void incrementScore(){
score+=1;
}
}
}
--------------------------------------------------------------------------------------------
Useful Blog : https://stackoverflow.com/questions/46283981/android-viewmodel-additional-arguments
VIEWMODELFACTORY & AndroidViewModel
AndroidViewModel is a viewmodel subclass which gives Application inside the constructor , but we still need to create a factory viewmodel for that.
By Default ViewModel Constructor Cannot have any Parameter , but if you want to pass any parameters (like Context , Application) , then you have to create a ViewModelFactory for that.
noteViewModel =
new ViewModelProvider(this,new NoteViewModelFactory(this.getApplication()))
.get(NoteViewModel.class);
package com.deepesh.notemaster;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
public class NoteViewModelFactory extends ViewModelProvider.AndroidViewModelFactory {
Application application;
public NoteViewModelFactory(@NonNull Application application) {
super(application);
this.application=application;
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
return (T) new NoteViewModel(application);
}
}
-------------------------------------------------------------------------------------------


Comments
Post a Comment