Android Retrofit ListView Tutorial Example Parse JSON Step By Step

retrofit android get json, android retrofit listview, android recyclerview retrofit, android spinner example to load json using retrofit, android google map draw path, android google map draw path between current location and destination

You are reading about Android Retrofit ListView Tutorial Example Parse JSON Step By Step.

Retrofit android tutorial will guide you to parse JSON data from the remote web server and then display this data in the ListView.

We will fetch/retrieve JSON data from MySQL database (server) using retrofit and will make custom listview with image and text.

In this tutorial, we will fetch the information like player name, city, country and image URL in JSON format with retrofit library.

Retrofit library makes our task easy to do http calls to the web service to retrieve the JSON data.

It also handles the cache of data in the proper manner.

Then a listview will showcase this information in a perfect format.

Last Look Of Retrofit ListView

Let us reach our goal step by step.

Step 1. Permission and Gradle lines

Open up your android studio and make a new fresh project with empty activity as a default activity.

When we want to get data from server, we need to use internet of the android device.

For this need, we will write one line in AndroidManifest.xml file. Below line will enable our app to use internet.

 <uses-permission android:name="android.permission.INTERNET"/>

After this, let us add some lines in the build.gradle(Module:app) file as per the below

 implementation 'com.squareup.retrofit2:retrofit:2.5.0'
 implementation 'com.squareup.retrofit2:converter-scalars:2.5.0'
 implementation 'com.squareup.picasso:picasso:2.71828'
  • First line will add the required classes to use retrofit library in our project.
  • Second line will enable us to use the coding lines of the scalar library.
  • By default, retrofit will not give us the JSON response in a string format. Scalar helps us to convert the JSON data into the string format.
  • Last line is for picasso library. This library will help us to load the images from URL and to maintain the image cache.

Step 2. Making Our Interface

Prepare a new JAVA class and give it a name MyInterface.java

Write down the below source code in MyInterface.java

import retrofit2.Call;
import retrofit2.http.GET;

public interface MyInterface {

    String JSONURL = "https://demonuts.com/Demonuts/JsonTest/Tennis/";

    @GET("json_parsing.php")
    Call<String> getString();
}
  • A string variable JSONURL contains the URL from which we will get our JSON data.
  • @GET annotation holds the name of the php file.
  • getString() function has the return type as a call back in the string format.

Step 3. Model class for ListView

Now make a new java class named ModelListView.java

Source code for ModelListView.java is looking like the following

  private String name, country, city, imgURL;

    public String getImgURL(){
        return imgURL;
    }

    public void setImgURL(String imgURL){
        this.imgURL = imgURL;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
  • Types of information we are getting from JSON is like name, city, country etc.
  • Above class includes getter ans setter information for all the types of the information.
  • These methods will help us to maintain data between the listview and the adapter class.

Step 4. Special layout file

Create a new layout resource file named retro_lv.xml and write the below code snippet in this file.

<?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="match_parent">

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"
        android:scaleType="fitXY"
        android:id="@+id/iv"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_marginTop="5dp"
            android:layout_weight="1"
            android:id="@+id/name"
            android:text="ddd"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:id="@+id/country"
            android:text="ddd"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:id="@+id/city"
            android:text="ddd"/>

    </LinearLayout>



</LinearLayout>
  • This file have one image view and three text views.
  • We will fetch image from the URL in this image view.
  • Textviews will hold the information like name, country, city etc.

Step 5. Retro Adapter

Time to make an adapter class for the listview.

Prepare a new class and named it as RetroAdapter.java

Following is the code structure for RetroAdapter.java class

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;

public class RetroAdapter extends BaseAdapter {

    private Context context;
    private ArrayList<ModelListView> dataModelArrayList;

    public RetroAdapter(Context context, ArrayList<ModelListView> dataModelArrayList) {

        this.context = context;
        this.dataModelArrayList = dataModelArrayList;
    }

    @Override
    public int getViewTypeCount() {
        return getCount();
    }
    @Override
    public int getItemViewType(int position) {

        return position;
    }

    @Override
    public int getCount() {
        return dataModelArrayList.size();
    }

    @Override
    public Object getItem(int position) {
        return dataModelArrayList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;

        if (convertView == null) {
            holder = new ViewHolder();
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.retro_lv, null, true);

            holder.iv = (ImageView) convertView.findViewById(R.id.iv);
            holder.tvname = (TextView) convertView.findViewById(R.id.name);
            holder.tvcountry = (TextView) convertView.findViewById(R.id.country);
            holder.tvcity = (TextView) convertView.findViewById(R.id.city);

            convertView.setTag(holder);
        }else {
            // the getTag returns the viewHolder object set as a tag to the view
            holder = (ViewHolder)convertView.getTag();
        }

        Picasso.get().load(dataModelArrayList.get(position).getImgURL()).into(holder.iv);
        holder.tvname.setText("Name: "+dataModelArrayList.get(position).getName());
        holder.tvcountry.setText("Country: "+dataModelArrayList.get(position).getCountry());
        holder.tvcity.setText("City: "+dataModelArrayList.get(position).getCity());

        return convertView;
    }

    private class ViewHolder {

        protected TextView tvname, tvcountry, tvcity;
        protected ImageView iv;
    }

}
  • Look at the constructor in the above adapter class. It has two parameters.
  • First parameters will get context while other one will get the arraylist with the objects of the ModelListView class.
  • getView() method contain the necessary coding lines to fill the information.

Following lines are populating the row of the listview.

 Picasso.get().load(dataModelArrayList.get(position).getImgURL()).into(holder.iv);
        holder.tvname.setText("Name: "+dataModelArrayList.get(position).getName());
        holder.tvcountry.setText("Country: "+dataModelArrayList.get(position).getCountry());
        holder.tvcity.setText("City: "+dataModelArrayList.get(position).getCity());
  • First line line will load the image from the URL using picasso library.
  • Other three lines will fill the name, country and city respectively.

Step 6. Main Modifications

Now just need to change the main files.

First of all, add the below code snippet in the activity_main.xml file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:textSize="26sp"
        android:text="Below ListView is populated from RETROFIT JSON Data"
        android:textColor="#000"
        />

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/lv"
        android:layout_marginTop="10dp"/>


</LinearLayout>
  • Above file holds one text view and one listview.
  • Text view is static and it is saying that below listview have data which is parsed with retrofit.

Now in the MainActivity.java file, you should write the following coding lines

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;

public class MainActivity extends AppCompatActivity {

    private ListView listView;
    private RetroAdapter retroAdapter;

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

        listView = findViewById(R.id.lv);

        getJSONResponse();

    }

    private void getJSONResponse(){

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(MyInterface.JSONURL)
                .addConverterFactory(ScalarsConverterFactory.create())
                .build();

        MyInterface api = retrofit.create(MyInterface.class);

        Call<String> call = api.getString();

        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                Log.i("Responsestring", response.body().toString());
                //Toast.makeText()
                if (response.isSuccessful()) {
                    if (response.body() != null) {
                        Log.i("onSuccess", response.body().toString());

                        String jsonresponse = response.body().toString();
                        writeListView(jsonresponse);

                    } else {
                        Log.i("onEmptyResponse", "Returned empty response");//Toast.makeText(getContext(),"Nothing returned",Toast.LENGTH_LONG).show();
                    }
                }
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {

            }
        });
    }

    private void writeListView(String response){

        try {
            //getting the whole json object from the response
            JSONObject obj = new JSONObject(response);
            if(obj.optString("status").equals("true")){

                ArrayList<ModelListView> modelListViewArrayList = new ArrayList<>();
                JSONArray dataArray  = obj.getJSONArray("data");

                for (int i = 0; i < dataArray.length(); i++) {

                    ModelListView modelListView = new ModelListView();
                    JSONObject dataobj = dataArray.getJSONObject(i);

                    modelListView.setImgURL(dataobj.getString("imgURL"));
                    modelListView.setName(dataobj.getString("name"));
                    modelListView.setCountry(dataobj.getString("country"));
                    modelListView.setCity(dataobj.getString("city"));

                    modelListViewArrayList.add(modelListView);

                }

                retroAdapter = new RetroAdapter(this, modelListViewArrayList);
                listView.setAdapter(retroAdapter);

            }else {
                Toast.makeText(MainActivity.this, obj.optString("message")+"", Toast.LENGTH_SHORT).show();
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

}

Deep Into Main Activity

Let us check what will main activity code actually do in this app.

First of all in onCreate() method, compiler will call getJSONResponse() method.

Source code for getJSONResponse() method is as the below

  private void getJSONResponse(){

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(MyInterface.JSONURL)
                .addConverterFactory(ScalarsConverterFactory.create())
                .build();

        MyInterface api = retrofit.create(MyInterface.class);

        Call<String> call = api.getString();

        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                Log.i("Responsestring", response.body().toString());
                //Toast.makeText()
                if (response.isSuccessful()) {
                    if (response.body() != null) {
                        Log.i("onSuccess", response.body().toString());

                        String jsonresponse = response.body().toString();
                        writeListView(jsonresponse);

                    } else {
                        Log.i("onEmptyResponse", "Returned empty response");//Toast.makeText(getContext(),"Nothing returned",Toast.LENGTH_LONG).show();
                    }
                }
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {

            }
        });
    }
  • Here, compiler will create the object of the Retrofit class. During this process, it will bind the URL using .baseUrl() method.
  • Then compiler will create the object of the MyInterface class which we have created in Step 2.
  • An object of the Call<String> will use call.enqueue() to make the http call.
  • When system gives the final JSON response then compiler will call onResponse() method.
  • Inside the onResponse() method, we will get the JSON response in the string format.
  • Then call to writeListView() method will be taken place.

Code for writeListView() method is as the following

 private void writeListView(String response){

        try {
            //getting the whole json object from the response
            JSONObject obj = new JSONObject(response);
            if(obj.optString("status").equals("true")){

                ArrayList<ModelListView> modelListViewArrayList = new ArrayList<>();
                JSONArray dataArray  = obj.getJSONArray("data");

                for (int i = 0; i < dataArray.length(); i++) {

                    ModelListView modelListView = new ModelListView();
                    JSONObject dataobj = dataArray.getJSONObject(i);

                    modelListView.setImgURL(dataobj.getString("imgURL"));
                    modelListView.setName(dataobj.getString("name"));
                    modelListView.setCountry(dataobj.getString("country"));
                    modelListView.setCity(dataobj.getString("city"));

                    modelListViewArrayList.add(modelListView);

                }

                retroAdapter = new RetroAdapter(this, modelListViewArrayList);
                listView.setAdapter(retroAdapter);

            }else {
                Toast.makeText(MainActivity.this, obj.optString("message")+"", Toast.LENGTH_SHORT).show();
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

Let us first check the JSON data which we get from the server.

{
    "status": "true",
    "message": "Data fetched successfully!",
    "data": [
        {
            "id": "1",
            "name": "Roger Federer",
            "country": "Switzerland",
            "city": "Basel"
        },
        {
            "id": "2",
            "name": "Rafael Nadal",
            "country": "Spain",
            "city": "Madrid"
        },
        {
            "id": "3",
            "name": "Novak Djokovic",
            "country": "Serbia",
            "city": "Monaco"
        },
        {
            "id": "4",
            "name": "Andy Murray",
            "country": "United Kingdom",
            "city": "London"
        },
        {
            "id": "5",
            "name": "Maria Sharapova",
            "country": "Russia",
            "city": "Moscow"
        },
        {
            "id": "6",
            "name": "Caroline Wozniacki",
            "country": "Denmark",
            "city": "Odense"
        },
        {
            "id": "7",
            "name": "Eugenie Bouchard",
            "country": "Canada",
            "city": " Montreal"
        },
        {
            "id": "8",
            "name": "Ana Ivanovic",
            "country": "Serbia",
            "city": "Belgrade"
        }
    ]
}
  • Now understand the writeListView() method and also check the JSON data simultaneously.
  • Here, compiler will first get the json array from the field “data
  • Then it will run one for loop. In the every iteration of the for loop, compiler will fetch the information and will set it in the object of the ModelListView class.
  • After the completion of the for loop, compiler will set the arraylist to the second parameter of the RetroAdapter.

Finally, adapter is set to the listview and whooom, our example is finish!!

Download Code for Android Retrofit ListView Example

Download Json_ListView_Retrofit Source Code