Heard about ViewModel in android? Android ViewModel is an architecture component that is designed to store UI related data. According to Android Developer Website.
The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.
If you remember one of our last Retrofit Tutorial where we learned about fetching JSON data from a URL. Now if one of our activity has some data on it fetched from server, but if for some reasons (for example orientation changes) the activity is recreated it will fetch the data from the server again. Fetching the same data from the server is a waste of resources. An efficient solution here is to separate the view data ownership from UI Controller logic.
So, in this Android View Model tutorial we will do the same thing we did in the previous Retrofit Tutorial but here we will be using the ViewModel architecture.
Table of Contents
Setting Up Android Project with RecyclerView and Retrofit
Creating a new Android Studio Project
- As always the first step is creating a new Android Studio Project. And in that project we will see how to work with Android ViewModel.
- I have created a project using an EmptyActivity named AndroidViewModel.
API to fetch data
- You can use any URL if you have any, to fetch data. Here I am going to use the following URL.
https://www.simplifiedcoding.net/demos/marvel/
- The above URL is returning a list of Marvel Super Heroes. You can open the URL to see what it is returning. It is the same URL that we used while learning Retrofit JSON.
Adding Required Dependency
For this project we are going to use the following dependencies.
- RecyclerView – To display list of superheroes.
- Glide – To load image from URL.
- Retrofit – For fetching data from the URL.
- ViewModel – The architectural component
So the first we will add all the above mentioned dependencies in the app level build.gradle file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:27.1.1' implementation 'com.android.support.constraint:constraint-layout:1.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' //adding dependencies implementation 'com.android.support:recyclerview-v7:27.1.1' implementation 'com.squareup.retrofit2:retrofit:2.4.0' implementation 'com.squareup.retrofit2:converter-gson:2.4.0' implementation 'com.github.bumptech.glide:glide:4.3.1' annotationProcessor 'com.github.bumptech.glide:compiler:4.3.1' implementation "android.arch.lifecycle:extensions:1.1.0" implementation "android.arch.lifecycle:viewmodel:1.1.0" } |
After adding all the dependencies sync your project.
Creating the POJO class for Hero
- Create a new class named Hero.java and write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | package com.example.belalkhan.androidviewmodel; public class Hero { private String name; private String realname; private String team; private String firstappearance; private String createdby; private String publisher; private String imageurl; private String bio; public Hero(String name, String realname, String team, String firstappearance, String createdby, String publisher, String imageurl, String bio) { this.name = name; this.realname = realname; this.team = team; this.firstappearance = firstappearance; this.createdby = createdby; this.publisher = publisher; this.imageurl = imageurl; this.bio = bio; } public String getName() { return name; } public String getRealname() { return realname; } public String getTeam() { return team; } public String getFirstappearance() { return firstappearance; } public String getCreatedby() { return createdby; } public String getPublisher() { return publisher; } public String getImageurl() { return imageurl; } public String getBio() { return bio; } } |
Setting Up RecyclerView
Creating RecyclerView and RecyclerView Layout
- Now come inside activity_main.xml and create a RecyclerView here, in this RecyclerView we will display the Hero List.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> |
- Now we will also create one more layout resource file for the RecyclerView.
- Create a layout resource file named recyclerview_layout.xml and write the following xml code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="200dp" /> <TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAlignment="center" android:textAppearance="@style/Base.TextAppearance.AppCompat.Large" /> </LinearLayout> |
Creating RecyclerView Adapter
- Now we need the RecyclerView Adapter. We are going to use the below code for this. If you are not sure what it is all about, you can check the RecyclerView Tutorial.
- So just create a new class named HeroesAdapter.java and write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | package com.example.belalkhan.androidviewmodel; import android.content.Context; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; import java.util.List; public class HeroesAdapter extends RecyclerView.Adapter<HeroesAdapter.HeroViewHolder> { Context mCtx; List<Hero> heroList; public HeroesAdapter(Context mCtx, List<Hero> heroList) { this.mCtx = mCtx; this.heroList = heroList; } @NonNull @Override public HeroViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(mCtx).inflate(R.layout.recyclerview_layout, parent, false); return new HeroViewHolder(view); } @Override public void onBindViewHolder(@NonNull HeroViewHolder holder, int position) { Hero hero = heroList.get(position); Glide.with(mCtx) .load(hero.getImageurl()) .into(holder.imageView); holder.textView.setText(hero.getName()); } @Override public int getItemCount() { return heroList.size(); } class HeroViewHolder extends RecyclerView.ViewHolder { ImageView imageView; TextView textView; public HeroViewHolder(View itemView) { super(itemView); imageView = itemView.findViewById(R.id.imageView); textView = itemView.findViewById(R.id.textView); } } } |
Setting Up RecyclerView
- Now come back to MainActivity.java and write the following codes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class MainActivity extends AppCompatActivity { RecyclerView recyclerView; HeroesAdapter adapter; List<Hero> heroList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = findViewById(R.id.recyclerview); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(this)); } } |
- Now we will setup the Retrofit to fetch data from URL.
Setting Up Retrofit
The API Interface
- Create a new interface Api.java.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package com.example.belalkhan.androidviewmodel; import java.util.List; import retrofit2.Call; import retrofit2.http.GET; public interface Api { String BASE_URL = "https://simplifiedcoding.net/demos/"; @GET("marvel") Call<List<Hero>> getHeroes(); } |
- Till here we done the things that we have already learned in the previous tutorials. Now we will use ViewModel architecture to load the data in RecyclerView.
Using Android ViewModel to load data Asynchronously using Retrofit
Creating Android ViewModel
- For creating a ViewModel, we need to create a class that will extend the ViewModel class.
- Here I am creating a class named HeroViewModel.java.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | package com.example.belalkhan.androidviewmodel; import android.arch.lifecycle.LiveData; import android.arch.lifecycle.MutableLiveData; import android.arch.lifecycle.ViewModel; import android.widget.Toast; import java.util.List; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class HeroesViewModel extends ViewModel { //this is the data that we will fetch asynchronously private MutableLiveData<List<Hero>> heroList; //we will call this method to get the data public LiveData<List<Hero>> getHeroes() { //if the list is null if (heroList == null) { heroList = new MutableLiveData<List<Hero>>(); //we will load it asynchronously from server in this method loadHeroes(); } //finally we will return the list return heroList; } //This method is using Retrofit to get the JSON data from URL private void loadHeroes() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(Api.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); Api api = retrofit.create(Api.class); Call<List<Hero>> call = api.getHeroes(); call.enqueue(new Callback<List<Hero>>() { @Override public void onResponse(Call<List<Hero>> call, Response<List<Hero>> response) { //finally we are setting the list to our MutableLiveData heroList.setValue(response.body()); } @Override public void onFailure(Call<List<Hero>> call, Throwable t) { } }); } } |
- The fetch using Retrofit part is exactly the same here that we already learned in the Retrofit Tutorial.
- And the ViewModel thing is very easy, we only have a method named getHeroes(). Inside this method we are checking if the List is null then we will get it asynchronously. Remember we need to use MutableLiveData and LiveData classes for storing the List and the rest is managed by the ViewModel component. So you do not need to worry about other things.
Using the Android ViewModel for Displaying the Hero List
- Write the following code at the end of onCreate() method in MainActivity.java.
1 2 3 4 5 6 7 8 9 10 11 | HeroesViewModel model = ViewModelProviders.of(this).get(HeroesViewModel.class); model.getHeroes().observe(this, new Observer<List<Hero>>() { @Override public void onChanged(@Nullable List<Hero> heroList) { adapter = new HeroesAdapter(MainActivity.this, heroList); recyclerView.setAdapter(adapter); } }); |
- Now you can run your application, to check if it is working or not.

As you can see it is working fine. The advantage of doing this way is, if our activity recreates then it will not fetch the data again making our application more efficient. And yes you can get my source code from the below given GitHub repository.
Android ViewModel Example Source Code
I hope you found this tutorial helpful. If you are having any confusion regarding this Android ViewModel tutorial then leave your comments. And please don’t forget to SHARE this post with your friends. Thank You.

Hi, my name is Belal Khan and I am a Google Developers Expert (GDE) for Android. The passion of teaching made me create this blog. If you are an Android Developer, or you are learning about Android Development, then I can help you a lot with Simplified Coding.
I’m a selftaught and a beginner to programing from central Africa.
I want a kotlin code with one editText with an onfocuschange listener. Onfocuschange it should it should square the input.
I have tried alot to search online but it is not available ( best of my search)
I am Belal Khan, i need the retrofit CRUD operetion demo .
Check this video series I posted, it covers everything about retrofit https://goo.gl/pwGVcJ
Is your view model example is MVVM ??
I think this has to be the simplest explanation of viewModel out there.
Thanks
Perfect Tutorial. Thanks.
can you send me the source code
Hello Belal, can we use ViewModel with Volley also. Which is more prefereable?
Use retrofit, volley is obsolete now.
I tried the code and I have a question that when I keep rotating the screen then onChanged is keep getting called, is this expected???
As you know, any View Models associated with an Activity or Fragment are designed specifically to persist across configuration changes, effectively providing caching for the data they store. We should use observe method to add an Observer implementation whose onChanged handler will be triggered whenever the underlying data changes. Because your View Model lifecycle is based on your application—rather than the parent Activity or
Fragment—the View Model’s Live Data’s loading function won’t be interrupted by a device configuration change.
Similarly, your results are implicitly cached across device configuration changes. After a rotation,
when observe is called on the View Model’s data, it will immediately return the last result set via
the onChanged handler—without the View Model’s loadData method (loadHeroes() in Belal khan tutorial) being called. This saves signifcant time and battery power by eliminating duplicative network downloads and the associated processing. I hope this would be helpful.
Hello Belal Khan!
Thankyou for yr awesome tutoriels!
I have this problem i use retrofit(for the remote backend) for send image to the php server uploaded from the camera!
The type of the image is byte in my POJO class and in my server i have the filename!
What i should do ?
Thanks!
pls mvvm with rest api tutorial post it
// Lifecycle extensions
implementation “android.arch.lifecycle:extensions:1.1.1”
// Lifecycle viewmodel
implementation “android.arch.lifecycle:viewmodel:1.1.1”
Use the above dependencies, It will help.
HeroesViewModel model = ViewModelProviders.of(this).get(HeroesViewModel.class);
I’m getting an error in(.of) . Help me to resolve this, i have the dependencies also
Use this dependency
implementation ‘android.arch.lifecycle:extensions:1.1.1’
Example is missing code to handle 400 and 500 series errors.
Can you please show how to implement this with repository as you are getting the data from ViewModel itself which should come from a repository as per the workflow provided by Google. I see the repository part missing here Thanking you in advance.
kindly explain this how you can call ViewModelProviders.of(this).get(HeroesViewModel.class);
are you use an androidx library for that…or what ?
loadheroes() executes asynchronously, that means return might call before getting data from webservice and in that case herolist will be null. How to solve this issue??
I am getting annotations are not allowed here error in API.java file when I type @GET(“marvel”);
Hello Bilal,
Is this MVVM Model ?
hello, what is the marvel parameter of GET in Api interface
unable to to download code. its not getting downloaded even when i subscribed your youtube channel. wondering if you know this issue
Click the download link,
You will see the download page where link is locked, now follow these steps
#1 Click on Subscribe Button, it will open a new tab, in this tab subscribe if you are not already subscribed. If you are already subscribed ignore this tab and go back to the download page. Make sure you don’t open the download page again and go back to the already opened page.
#2 Wait for few seconds and the download link will unlock.
Hello sir, can this tutorial be applied in Kotlin?
Check the youtube channel, I have a complete playlist about it with kotlin.
cn you send me a link for this example in kotlin?