<p><strong> <span style="color: #008000;">ViewModelExample</span></strong> is a very<em> </em>straightforward app with buttons that increase Or decrease the no of items. The finished app has a bug though; if you rotate the phone, your selected number of items will again set up with the initial value.</p>
<p><img class="alignnone size-medium wp-image-369" src="https://c1ctech.com/wp-content/uploads/2018/04/Screenshot_2018-04-27-21-40-391-180x300.png" alt="" width="180" height="300" /> <img class="alignnone size-medium wp-image-370" src="https://c1ctech.com/wp-content/uploads/2018/04/Screenshot_2018-04-27-21-41-191-300x180.png" alt="" width="300" height="180" /></p>
<p>What’s going on? Rotating a device is one of a few <span style="color: #008000;"><a style="color: #008000;" href="https://developer.android.com/guide/topics/manifest/activity-element.html#config" data-href="https://developer.android.com/guide/topics/manifest/activity-element.html#config"><strong>configuration changes</strong></a></span> that an app can go through during its lifetime. When configurations changed during run time (such as screen orientation, keyboard availability, and language), Android usually destroys application’s existing Activity or Fragment and recreate it.</p>
<h3><span style="color: #000080;"><strong>ViewModel</strong></span></h3>
<p>At <strong><span style="color: #008000;">Google I/O 2017</span></strong>, the Android Framework team introduced a new set of <strong><span style="color: #008000;"><a style="color: #008000;" href="https://developer.android.com/topic/libraries/architecture/index.html" data-href="https://developer.android.com/topic/libraries/architecture/index.html">Architecture Components</a></span></strong>, one of which deals with this exact rotation issue.</p>
<p>The <span style="color: #008000;"><a style="color: #008000;" href="https://developer.android.com/reference/android/arch/lifecycle/ViewModel.html" data-href="https://developer.android.com/reference/android/arch/lifecycle/ViewModel.html"><strong>ViewModel</strong></a></span> class is designed to hold and manage UI-related data in a life-cycle conscious way. This allows data to survive configuration changes such as screen rotations.</p>
<p>Download <strong>Github</strong> code from <a href="https://github.com/arunk7839/ViewModelExample"><span style="color: #00ff00;"><strong>here</strong></span></a>.</p>
<p><span class="embed-youtube" style="text-align:center; display: block;"><amp-youtube data-videoid="15oSrAB0fxk" data-param-rel="1" data-param-showsearch="0" data-param-showinfo="1" data-param-iv_load_policy="1" data-param-fs="1" data-param-hl="en-US" data-param-autohide="2" data-param-wmode="transparent" width="1200" height="675" layout="responsive"><a href="https://www.youtube.com/watch?v=15oSrAB0fxk" placeholder><amp-img src="https://i.ytimg.com/vi/15oSrAB0fxk/hqdefault.jpg" alt="YouTube Poster" layout="fill" object-fit="cover"><noscript><img src="https://i.ytimg.com/vi/15oSrAB0fxk/hqdefault.jpg" loading="lazy" decoding="async" alt="YouTube Poster"></noscript></amp-img></a></amp-youtube></span></p>
<p>Previously, you might have used <strong><span style="color: #008000;"><a style="color: #008000;" href="https://developer.android.com/reference/android/app/Activity.html#onRetainNonConfigurationInstance%28%29" data-href="https://developer.android.com/reference/android/app/Activity.html#onRetainNonConfigurationInstance()">onRetainNonConfigurationInstance</a></span></strong> to save this data during a configuration change and unpack it on the other end.</p>
<p>In the diagram below, you can see the lifecycle of an Activity which undergoes a rotation and then is finally finished. The lifetime of the ViewModel is shown next to the associated Activity lifecycle. Note that ViewModels can be easily used with both Fragments and Activities, which I’ll call <span style="color: #008000;"><strong>UI controllers</strong></span>. This example focuses on Activities.</p>
<p><img class="wp-image-374 size-full aligncenter" src="https://c1ctech.com/wp-content/uploads/2018/04/Capture.jpg" alt="" width="514" height="491" />The ViewModel exists when you first request a ViewModel (usually in the onCreate the Activity) until the Activity is finished and destroyed. onCreate may be called several times during the life of an Activity, such as when the app is rotated, but the ViewModel survives throughout.</p>
<h4><span style="color: #000080;"><strong>There are three steps to setting up and using a ViewModel:</strong></span></h4>
<h4><strong><span style="color: #008000;">Step 1: Create a ViewModel class</span></strong></h4>
<pre>public class OrderViewModel extends ViewModel {

 public int orderedCoffee = 0;

 public int orderedTea = 0;

 public int orderedColddrink = 0;

}</pre>
<h4></h4>
<h4><strong><span style="color: #008000;">Step 2: Set up communications between your ViewModel and your UI controller</span></strong></h4>
<p>Your UI controller ( Activity or Fragment) needs to know about your ViewModel. This is so your UI controller can display the data and update the data when UI interactions occur, such as pressing a button to increase or decrease the no of items.</p>
<pre>OrderViewModel mViewModel;

@Override
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

mViewModel = ViewModelProviders.of(this).get(OrderViewModel.class);
displayNoOfCoffee(mViewModel.orderedCoffee);
}

</pre>
<h4></h4>
<h4><strong><span style="color: #008000;">Step 3: Use the ViewModel in your UI Controller</span></strong></h4>
<p>To access or change UI data, you can now use the data in your ViewModel. Here’s an example of the new onCreate method and a method for updating the no of items :</p>
<pre>OrderViewModel mViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
btnIncreaseCoffee = (Button) findViewById(R.id.btn_increase_coffee);
btnDecreaseCoffee = (Button) findViewById(R.id.btn_decrease_coffee);


noOfCoffee = (TextView) findViewById(R.id.tv_no_ofcoffee);
mViewModel = ViewModelProviders.of(this).get(OrderViewModel.class);
displayNoOfCoffee(mViewModel.orderedCoffee);
public void displayNoOfCoffee(int coffee) {

 noOfCoffee.setText(coffee + "");
}
@Override
public void onClick(View view) {

 switch (view.getId()) {
 case R.id.btn_increase_coffee: {
 mViewModel.orderedCoffee = mViewModel.orderedCoffee + 1;
 displayNoOfCoffee(mViewModel.orderedCoffee);
 break;
 }
 case R.id.btn_decrease_coffee: {
 if (mViewModel.orderedCoffee >; 0) {
 mViewModel.orderedCoffee = mViewModel.orderedCoffee - 1;
 displayNoOfCoffee(mViewModel.orderedCoffee);
 }
 break;
 }
}</pre>
<p>The first time the <strong><span style="color: #008000;"><a style="color: #008000;" href="https://developer.android.com/reference/android/arch/lifecycle/ViewModelProviders.html#of%28android.support.v4.app.Fragment%29" data-href="https://developer.android.com/reference/android/arch/lifecycle/ViewModelProviders.html#of(android.support.v4.app.Fragment)">ViewModelProviders</a> </span></strong>method is called by MainActivity, it creates a new ViewModel instance. When this method is called again, which happens whenever onCreate is called, it will return the pre-existing ViewModel associated with the specific <strong><span style="color: #008000;">ViewModelExample</span></strong> MainActivity. This is what preserves the data.</p>
<h3><strong><span style="color: #000080;">Creating New Project</span></strong></h3>
<p>1.In Android Studio, go to <span style="color: #008000;"><strong>File </strong><strong>⇒</strong><strong> New Project</strong></span> and fill all the details required to create a new project. When it prompts to select a default activity, select <span style="color: #008000;"><strong>Blank Activity</strong> </span>and proceed.</p>
<p>2.Open <span style="color: #008000;"><strong>build.gradle</strong></span> and add ViewModel dependency.</p>
<p><span style="color: #000080;"><strong>Build.gradle</strong></span></p>
<pre>dependencies {
 
 <span style="color: #008000;"><strong>//viewmodel dependency</strong></span>
 implementation "android.arch.lifecycle:extensions:1.0.0"
 annotationProcessor "android.arch.lifecycle:compiler:1.0.0"

}</pre>
<p>3. Open <strong><span style="color: #008000;">OrderViewModel.Java</span></strong> and write the below code.</p>
<p><strong><span style="color: #000080;">OrderViewModel.Java</span></strong></p>
<pre>package com.example.lenovo.viewmodelexample;

import android.arch.lifecycle.ViewModel;

public class OrderViewModel extends ViewModel {

 public int orderedCoffee = 0;

 public int orderedTea = 0;

 public int orderedColddrink = 0;

}</pre>
<p>4. Open <strong><span style="color: #008000;">activity_main.xml</span></strong> and write the below code.Here to increase or decrease items i have created increase and decrease button.</p>
<p><strong><span style="color: #000080;">activity_main.xml</span></strong></p>
<!-- WP QUADS Content Ad Plugin v. 3.0.1 -->
<div class="quads-location quads-ad2" id="quads-ad2" style="float:none;margin:0px;">

</div>

<pre><;?xml version="1.0" encoding="utf-8"?>;
<;ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context="com.example.lenovo.viewmodelexample.MainActivity">;

 <;LinearLayout
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 android:padding="8dp">;

 <;TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:layout_marginBottom="15dp"
 android:layout_marginTop="15dp"
 android:fontFamily="sans-serif"
 android:text="Order what you would like to drink?"
 android:textColor="@android:color/holo_blue_dark"
 android:textSize="22sp" />;

 <;RelativeLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:padding="10dp">;

 <;TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_alignParentLeft="true"
 android:layout_centerVertical="true"
 android:fontFamily="sans-serif"
 android:text="No. of coffee"
 android:textColor="@android:color/holo_red_light"
 android:textSize="20sp" />;

 <;LinearLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_alignParentRight="true"
 android:layout_centerVertical="true"
 android:orientation="horizontal">;

 <;Button
 android:id="@+id/btn_increase_coffee"
 android:layout_width="40dp"
 android:layout_height="40dp"
 android:text="+" />;

 <;TextView
 android:id="@+id/tv_no_ofcoffee"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:padding="8dp" />;

 <;Button
 android:id="@+id/btn_decrease_coffee"
 android:layout_width="40dp"
 android:layout_height="40dp"
 android:text="-" />;

 <;/LinearLayout>;

 <;/RelativeLayout>;

 <;RelativeLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:padding="10dp">;

 <;TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_alignParentLeft="true"
 android:layout_centerVertical="true"
 android:fontFamily="sans-serif"
 android:text="No. of tea"
 android:textColor="@android:color/holo_red_light"
 android:textSize="20sp" />;

 <;LinearLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_alignParentRight="true"
 android:layout_centerVertical="true"
 android:orientation="horizontal">;

 <;Button
 android:id="@+id/btn_increase_tea"
 android:layout_width="40dp"
 android:layout_height="40dp"
 android:text="+" />;

 <;TextView
 android:id="@+id/tv_no_oftea"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:padding="8dp" />;

 <;Button
 android:id="@+id/btn_decrease_tea"
 android:layout_width="40dp"
 android:layout_height="40dp"
 android:text="-" />;

 <;/LinearLayout>;

 <;/RelativeLayout>;


 <;RelativeLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:padding="10dp">;

 <;TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_alignParentLeft="true"
 android:layout_centerVertical="true"
 android:fontFamily="sans-serif"
 android:text="No. of colddrink"
 android:textColor="@android:color/holo_red_light"
 android:textSize="20sp" />;

 <;LinearLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_alignParentRight="true"
 android:layout_centerVertical="true"
 android:orientation="horizontal">;

 <;Button
 android:id="@+id/btn_increase_colddrink"
 android:layout_width="40dp"
 android:layout_height="40dp"
 android:text="+" />;

 <;TextView
 android:id="@+id/tv_no_ofcolddrink"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:padding="8dp" />;

 <;Button
 android:id="@+id/btn_decrease_colddrink"
 android:layout_width="40dp"
 android:layout_height="40dp"
 android:text="-" />;

 <;/LinearLayout>;

 <;/RelativeLayout>;

 <;Button
 android:id="@+id/btn_order"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:layout_marginTop="10dp"
 android:text="order" />;
 <;/LinearLayout>;
<;/ScrollView>;

</pre>
<p>5. Open <span style="color: #008000;"><strong>MainActivity.Java</strong></span> and write the below code.Here I have set up connection between UI controller<br />
and ViewModel and also perform read and write operation on viewmodel.</p>
<p><strong><span style="color: #000080;">MainActivity.Java</span></strong></p>
<pre>package com.example.lenovo.viewmodelexample;

import android.arch.lifecycle.ViewModelProviders;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

 Button btnIncreaseCoffee, btnDecreaseCoffee, btnIncreaseTea, btnIncreaseColddrink, btnDecreaseTea, btnDecreaseColddrink;
 Button btnOrder;
 TextView noOfCoffee, noOfTea, noOfColddrink;
 OrderViewModel mViewModel;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 btnIncreaseCoffee = (Button) findViewById(R.id.btn_increase_coffee);
 btnDecreaseCoffee = (Button) findViewById(R.id.btn_decrease_coffee);

 btnIncreaseTea = (Button) findViewById(R.id.btn_increase_tea);
 btnDecreaseTea = (Button) findViewById(R.id.btn_decrease_tea);

 btnIncreaseColddrink = (Button) findViewById(R.id.btn_increase_colddrink);
 btnDecreaseColddrink = (Button) findViewById(R.id.btn_decrease_colddrink);

 btnOrder = (Button) findViewById(R.id.btn_order);

 noOfCoffee = (TextView) findViewById(R.id.tv_no_ofcoffee);
 noOfTea = (TextView) findViewById(R.id.tv_no_oftea);
 noOfColddrink = (TextView) findViewById(R.id.tv_no_ofcolddrink);

 //adding listener
 btnIncreaseCoffee.setOnClickListener(this);
 btnDecreaseCoffee.setOnClickListener(this);
 btnIncreaseTea.setOnClickListener(this);
 btnDecreaseTea.setOnClickListener(this);
 btnIncreaseColddrink.setOnClickListener(this);
 btnDecreaseColddrink.setOnClickListener(this);
 btnOrder.setOnClickListener(this);


 mViewModel = ViewModelProviders.of(this).get(OrderViewModel.class);
 displayNoOfCoffee(mViewModel.orderedCoffee);
 displayNoOfTea(mViewModel.orderedTea);
 displayNoOfColddrink(mViewModel.orderedColddrink);

 }

 public void displayNoOfCoffee(int coffee) {
 noOfCoffee.setText(coffee + "");
 }

 public void displayNoOfTea(int tea) {
 noOfTea.setText(tea + "");
 }

 public void displayNoOfColddrink(int colddrink) {
 noOfColddrink.setText(colddrink + "");
 }

 @Override
 public void onClick(View view) {

 switch (view.getId()) {
 case R.id.btn_increase_coffee: {
 mViewModel.orderedCoffee = mViewModel.orderedCoffee + 1;
 displayNoOfCoffee(mViewModel.orderedCoffee);
 break;
 }
 case R.id.btn_decrease_coffee: {
 if (mViewModel.orderedCoffee >; 0) {
 mViewModel.orderedCoffee = mViewModel.orderedCoffee - 1;
 displayNoOfCoffee(mViewModel.orderedCoffee);
 }
 break;
 }
 case R.id.btn_increase_tea: {
 mViewModel.orderedTea = mViewModel.orderedTea + 1;
 displayNoOfTea(mViewModel.orderedTea);
 break;
 }
 case R.id.btn_decrease_tea: {
 if (mViewModel.orderedTea >; 0) {
 mViewModel.orderedTea = mViewModel.orderedTea - 1;
 displayNoOfTea(mViewModel.orderedTea);
 }
 break;
 }
 case R.id.btn_increase_colddrink: {
 mViewModel.orderedColddrink = mViewModel.orderedColddrink + 1;
 displayNoOfColddrink(mViewModel.orderedColddrink);
 break;
 }
 case R.id.btn_decrease_colddrink: {
 if (mViewModel.orderedColddrink >; 0) {
 mViewModel.orderedColddrink = mViewModel.orderedColddrink - 1;
 displayNoOfColddrink(mViewModel.orderedColddrink);
 }
 break;
 }
 case R.id.btn_order: {
 Toast.makeText(this, "\n" + mViewModel.orderedCoffee + " " + "Coffee" + "\n" + mViewModel.orderedTea + " " + "Tea" + "\n" +
 mViewModel.orderedColddrink + " " + "Colddrink" + "\n", Toast.LENGTH_LONG).show();
 break;
 }

 }

 }
}</pre>
<p><span style="color: #008000;"><strong>When you run the app it will look like this:</strong></span></p>
<figure id="attachment_372" aria-describedby="caption-attachment-372" style="width: 180px" class="wp-caption alignleft"><img class="wp-image-372 size-medium" src="https://c1ctech.com/wp-content/uploads/2018/04/Screenshot_2018-04-27-22-13-311-180x300.png" alt="" width="180" height="300" /><figcaption id="caption-attachment-372" class="wp-caption-text">Vertical Orientation</figcaption></figure>
<figure id="attachment_371" aria-describedby="caption-attachment-371" style="width: 300px" class="wp-caption alignnone"><img class="wp-image-371 size-medium" src="https://c1ctech.com/wp-content/uploads/2018/04/Screenshot_2018-04-27-22-14-261-300x180.png" alt="" width="300" height="180" /><figcaption id="caption-attachment-371" class="wp-caption-text">Horizontal Orientation</figcaption></figure>
<p> ;</p>


