Tuesday 6 November 2018

Android Architecture Components : View Model

Hi ,
Today I am going to share another demo in Android architecture series i.e. View Model  . Firstly let me explain a short introduction of View Model:

  • Survives Configuration changes i.e. Screen-rotation
  • Not same as onSaveInstanceState (it is used to store small amount of data)
  • View Model used for large data such as :Bitmap or user list
  • store and manage UI related data
  • Destroyed only if the user activity is completely destroyed, in onCleared()
  • Communication layer between DB and UI
For more understanding , please refer : Android Developer View Model


So as I previously said, View Model is used to retain the data of configuration changes. So here I am going to explain a demo code , to check that View Model is really helpful to retain data while configuration changes (switching between landscape and portrait mode) or not .

In my demo code , I am taking one integer array , and getting one random number from that array .That random number will show on text-view. I will take 2 text-views , to hold the random number fetching from integer array. Among these two text-views , one will show the number normally while configuration changes and other text-view will show the number using view-model.So let's start:

-> Firstly I am adding following dependencies in build.gradle(app) file :

implementation "android.arch.lifecycle:runtime:1.1.1"
implementation "android.arch.lifecycle:extensions:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"

-> Take one layout named : view_model_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textview7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="25sp"
        android:textColor="#085937"
        android:textStyle="bold"
        android:text="TextView" />

    <TextView
        android:id="@+id/textview8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textview7"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:textSize="25sp"
        android:textColor="#085937"
        android:textStyle="bold"
        android:text="TextView" />

</RelativeLayout>



-> Before moving to activity java class, I have sub-classed , ViewModel class , with name :
RandomNumViewModel.java  , please take a look on code:

package com.development.view_model;

import android.arch.lifecycle.ViewModel;

import java.util.Random;

public class RandomNumViewModel extends ViewModel {

private int[] items = new int[]{1, 2, 3, 44, 65, 87, 22, 65, 87, 22, 90, 63, 4, 8, 50};

private Random random = new Random();

/**
* mRandomNumber , this variable should retain its value,
* on configuration change
*/
private int mRandomNumber = 0;


/**
* used to create a random number from array
* @return
*/
public int createNumber(){
mRandomNumber = items[random.nextInt(items.length)];
return mRandomNumber;
}


/**
* used to get the random number
* @return
*/
public int getRandArrayElement(){
if(mRandomNumber == 0){
mRandomNumber = createNumber();
return mRandomNumber;
}else{
return mRandomNumber;
}
}

}


-> Now take a look on my java file , I have named it as : ViewModelActivity.java

package com.development.view_model;

import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import com.development.R;

import java.util.Random;

public class ViewModelActivity extends AppCompatActivity {
TextView txt,txt1;
private int[] items = new int[]{1, 2, 3, 44, 65, 87, 22, 65, 87, 22, 90, 63, 4, 8, 50};
private Random random = new Random();

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_model_layout);
txt = (TextView)findViewById(R.id.textview7);
txt1 = (TextView)findViewById(R.id.textview8);
int num = getRandArrayElement();

/**
* it's value should change on configuration change
*/
txt.setText(""+num); // normal way to set data on textview


/**
* Setting textview using View Model
* it's value should retain on configuration change
*/
RandomNumViewModel randomNumViewModel =
ViewModelProviders.of(this).get(RandomNumViewModel.class);

int num1 = randomNumViewModel.getRandArrayElement();

txt1.setText(""+num1);
}

public int getRandArrayElement(){
return items[random.nextInt(items.length)];
}
}


That's it , build and run the code, you can check that the value of one text-view will change , but value of another text-view will not change , while configuration changes (switching between landscape and portrait mode) , I have run my code , you can check the screen shots for various steps of screen-rotation:







       Portrait Mode

     



 Landscape Mode









Here in above screenshots, we can clearly see , that the second text-view , which is using View-Model , to show (retain) the number value , doesn't change while screen-rotation , but the first one changes its value. 

No comments:

Post a Comment

Advanced Kotlin Coroutines : Introduction

 Hi,  Today I am unwraping the topic in Kotin world i.e. Coroutine . If you want to get started with Kotlin coroutine and ease your daily de...