Fetch and show JSON data Using Retrofit – Example

Hi folks, in the last post we have used Volley Library to fetch and show data From API. Today we are going to look at most used and best networking library Retrofit. Retrofit is having more features then Volley.

What is Retrofit?

Retrofit is a type-safe HTTP client for Android and Java. It means that you can perform many network action without writing lots of line of code.

In this blog post, we are going fetch some world population JSON from an API and show that data into RecyclerView. So let’s get started

https://github.com/happysingh23828/Retrofit-Tutorial-AndroChef

The API will give a response as JSON. Here is the link you can check it out.

http://androchef.com/wp-content/uploads/2019/03/world-population-androchef.txt

In this API we are getting a list of countries with their rank, flag, population etc.

Steps to fetch and show JSON data using Retrofit

  • Add Dependencies to your gradle file.
    implementation 'com.squareup.picasso:picasso:2.71828' // For loading Images
    implementation 'com.google.code.gson:gson:2.8.5' // For mapping Json
    implementation 'com.squareup.retrofit2:retrofit:2.4.0' 
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0' //for converting JSON into Gson
  • Add Internet Permission in your AndroidManifest.xml
    <uses-permission android:name="android.permission.INTERNET" />
  • Now make a POJO class to store your one JSON object

Worldpopulation.java

import com.google.gson.annotations.SerializedName;

public class Worldpopulation {

    @SerializedName("country")
    private String mCountry;
    @SerializedName("flag")
    private String mFlag;
    @SerializedName("population")
    private String mPopulation;
    @SerializedName("rank")
    private Long mRank;

    public String getCountry() {
        return mCountry;
    }

    public void setCountry(String country) {
        mCountry = country;
    }

    public String getFlag() {
        return mFlag;
    }

    public void setFlag(String flag) {
        mFlag = flag;
    }

    public String getPopulation() {
        return mPopulation;
    }

    public void setPopulation(String population) {
        mPopulation = population;
    }

    public Long getRank() {
        return mRank;
    }

    public void setRank(Long rank) {
        mRank = rank;
    }

}
  • So as I told you we are going to show data in recyclerView .

activity_main.xml

<?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=".normalvolleycall.MainActivity">

    <Button
        android:id="@+id/btn_load_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/load_list_using_volley"
        android:layout_gravity="center"
        android:gravity="center"
        android:background="@color/colorPrimary"
        android:layout_margin="10dp"
        android:textColor="@android:color/white" />

    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:layout_gravity="center"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/flag_list_recyclerView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_margin="5dp">

    </android.support.v7.widget.RecyclerView>

</LinearLayout>
  • We need a custom layout for each recyclerview Item

single_world_population_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/single_item_linearlayout">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_margin="10dp"
        android:elevation="100dp"
        android:translationZ="10dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal"
            android:weightSum="6">

            <ImageView
                android:id="@+id/img_flag"
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:layout_gravity="center"
                android:padding="10dp"
                android:src="@drawable/ic_launcher_background"
                android:layout_weight="1"/>

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:orientation="vertical"
                android:layout_weight="3"
                android:layout_gravity="center"
                >

                <TextView
                    android:id="@+id/txt_rank"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Rank 1"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:textStyle="bold"
                    android:textSize="20sp"/>

                <TextView
                    android:id="@+id/txt_country_name"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="Country Name"
                    android:gravity="center"
                    android:textStyle="bold"

                    />

                <TextView
                    android:id="@+id/txt_population"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Population"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:textStyle="bold"
                    />
                
            </LinearLayout>

        </LinearLayout>
        
    </android.support.v7.widget.CardView>
    
</LinearLayout>
  • We also need a custom adaptor for recyclerView.

CustomRecyclerAdapter.java

package com.androchef.volley.normalvolleycall;

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.androchef.volley.R;
import com.squareup.picasso.Picasso;

import java.util.List;

public class CustomRecyclerAdapter extends RecyclerView.Adapter<CustomRecyclerAdapter.CustomRecyclerViewHolder> {

    private List<Worldpopulation> listOfPopulation;
    private Context context;

    public CustomRecyclerAdapter(List<Worldpopulation> listOfPopulation, Context context) {
            this.listOfPopulation = listOfPopulation;
            this.context = context;
    }

    @NonNull
    @Override
    public CustomRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new CustomRecyclerViewHolder(LayoutInflater.from(context).inflate(R.layout.single_world_population_item,viewGroup,false));
    }

    @Override
    public void onBindViewHolder(@NonNull CustomRecyclerViewHolder customRecyclerViewHolder, int i) {
        customRecyclerViewHolder.bind(listOfPopulation.get(i));
    }

    @Override
    public int getItemCount() {
        return listOfPopulation.size();
    }

    class CustomRecyclerViewHolder extends RecyclerView.ViewHolder{

        View view;
        TextView countryName,countryPopulationCount,countryRank;
        ImageView countryFlag;

        CustomRecyclerViewHolder(@NonNull View itemView) {
            super(itemView);
            this.view = itemView;
            countryFlag = view.findViewById(R.id.img_flag);
            countryName = view.findViewById(R.id.txt_country_name);
            countryRank = view.findViewById(R.id.txt_rank);
            countryPopulationCount = view.findViewById(R.id.txt_population);
        }

        void bind(Worldpopulation worldpopulation){
            countryName.setText(worldpopulation.getCountry());
            countryPopulationCount.setText(worldpopulation.getPopulation());
            countryRank.setText(String.valueOf(worldpopulation.getRank()));
            Picasso.get().load(worldpopulation.getFlag()).into(countryFlag);
        }
    }
}
  • Now fetching and showing data using retrofit library
  • we need to create an API interface to specify which HTTP method need to call or in which form we need our Response.
//Retrofit turns your HTTP API into a Java interface.
    //Annotations on the interface methods and its parameters indicate how a request will be handled.
    public interface ApiInterface {

        // Request method and URL Given in the notation
        @GET("/wp-content/uploads/2019/03/world-population-androchef.txt")
        Call <List<Worldpopulation>> loadWordPopulationList();

    }
  • so here I defined an interface which has one method called loadWordPopulationList(). This is GET type HTTP method and it will return the list of WorlpPopulation Objects.
  • Now we will create a Retrofit Object with GsonCOnverterFactory which helps JSON response to convert into GSON.
String baseUrl = "http://androchef.com";

        // Creating a retrofit object and adding GsonConverterFactory which uses GSon for JSON
        Retrofit retrofit = new Retrofit.Builder().
                baseUrl(baseUrl).
                addConverterFactory(GsonConverterFactory.create()).build();

        ApiInterface apiInterface = retrofit.create(ApiInterface.class);

        Call<List<Worldpopulation>> apiCall = apiInterface.loadWordPopulationList();
  • in the last line we are getting a call object. we will use it to call and fetch the API
 //Calling the API to fetch Data
        apiCall.enqueue(new Callback<List<Worldpopulation>>() {
            @Override
            public void onResponse(Call<List<Worldpopulation>> call, Response<List<Worldpopulation>> response) {

                //updating or notifying adapter to show latest fetched list
                listOfWorldPopulations.clear();
                listOfWorldPopulations.addAll(response.body());
                adapter.notifyDataSetChanged();

                //hide progress bar
                progressBar.setVisibility(View.GONE);
            }

            @Override
            public void onFailure(Call<List<Worldpopulation>> call, Throwable t) {
                //hide progress bar
                progressBar.setVisibility(View.GONE);

                //when we got some network error while fetching data
                Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });

I hope you got some clarity on Retrofit Library. If you have some kind of confusion let me know in the comment section. Also if you find this helpful please share this with your developer friends. 🙂

Github Source Code Link

https://github.com/happysingh23828/Retrofit-Tutorial-AndroChef

Posted by Happy Singh

Android Developer

Leave a Reply

Your email address will not be published. Required fields are marked *