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

Popular posts from this blog

React Js + React-Redux (part-2)

React Js + CSS Styling + React Router (part-1)

ViteJS (Module Bundlers, Build Tools)