Android Json Parsing using Gson and RecyclerView

In this tutorial, we are going to learn how to parse Json object in android application using Gson. The resulting parsed object will be used to populate a RecyclerView.
JSON stands for JavaScript Object Notation and is use for data interchange between android application and a server.
A more detailed definition was taken from JSON website – “JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition – December 1999″.
Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.
There are a few open-source projects that can convert Java objects to JSON. However, most of them require that you place Java annotations in your classes; something that you can not do if you do not have access to the source-code. Most also do not fully support the use of Java Generics. Gson considers both of these as very important design goals.
What we will basically do in this tutorial, is to make a request to a remote server and return a Json string as response, thereafter, the response object will be parsed with Gson library and the resulting data will be bind to android RecycleView.
We will make use of Volley for the network call. Volley is an HTTP library that makes networking for Android apps easier and most importantly, faster. Volley is available through the open AOSP repository.
If you want to a simple tutorial on how to parse Json in android using HttpClient, I wrote a tutorial on this topic. I will suggest you read it first before you proceed with this.
Before we go deeper into this tutorial, it is important for us to understand what we are planning to achieve. Below is the screen-shot of the application we will be creating.
android Gson
We are going to use android RecycleView. We will create an Adapter for the RecycleView widget. The Adapter will inflate a custom layout file we will create which will hold the UI for the RecycleView items.
This item layout file will contain three TextView widget controls that will hold –
1. Song Title
2. Song Year
3. Song Author
Lets start to soil our hands on code. we will create our project in our IDE. For this tutorial, I am using the following tools and environment, feel free to use what works for you.
Windows 7
Android Studio
Sony Xperia ZL
Min SDK 14
Target SDK 23
To create a new android application project, follow the steps as stipulated below.
Go to File menu
Click on New menu
Click on Android Application
Enter Project name: AndroidGsonParser
Package: com.inducesmile.androidgsonparser
Select Blank Activity
Keep other default selections
Continue to click on next button until Finish button is active, then click on Finish Button.
Now that we have created our project, we are going to add internet permission in our project Manifest.xml file. We need this permission in order to make network calls. Copy and paste this single line of code inside your Manifest.xml file.
<uses-permission android:name="android.permission.INTERNET" />
Since we are going to use volley library for our network call, RecycleView to display our data to users and Gson library to parse the response Json string, we are going to add all these libraries to our project.
Open your app build.gradle file, copy and paste the code below inside the dependencies section and click on sync to download all our dependent libraries.
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:recyclerview-v7:23.1.1'
    compile 'com.mcxiaoke.volley:library:1.0.19'
    compile 'com.google.code.gson:gson:2.6.1'
}
The content of the Json object obtained as the response object is place in a remote .php file. The content of the file is shown below.
<?php

echo json_encode(Array(Array( "song_name" => "Hero", "song_id" => "1990", "artist_name" => "Enrique"), Array("song_name" => "African Queen", "song_id" => "2004", "artist_name" => "Tuface"), Array("song_name" => "Ifunanyi", "song_id" => "2012", "artist_name" => "PSquare")));

?>
Lets open the default layout file – activity_main.xml located in the res > layout folder. This is where we will add the RecycleView. It is a simple layout file. Copy and paste the code below to this layout file.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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.inducesmile.androidgsonparser.MainActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:scrollbars="vertical" />
</RelativeLayout>
We will move on to create the item list layout which our adapter will inflate. Right click on the layout folder and choose XML > Layout XML file. Name the file list_item.xml. Open this file and add the following code snippet in it.

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:background="@color/colorBackground">
    <TextView
        android:id="@+id/song_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:layout_marginTop="10dp"
        android:textSize="18dp"
        android:textStyle="bold"
        android:textColor="@color/colorPrimaryDark"/>
    <TextView
        android:id="@+id/song_year"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:textColor="#000"
        android:layout_below="@+id/song_title"
        android:layout_alignLeft="@+id/song_title"
        android:layout_alignStart="@+id/song_title"
        android:layout_marginTop="20dp" />
    <TextView
        android:id="@+id/song_author"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:textColor="#000"
        android:layout_alignTop="@+id/song_year"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />
</RelativeLayout>
We will create the RecycleView Adapter which will bind our data source to our application list items of the RecycleView.
Right click on the package folder located at java > package folder, click on New and select Java file. Name the file RecyclerViewAdapter.java. This adapter class will extends RecyclerView.Adapter<RecyclerViewHolders>. Open this file, copy and paste the code below to the file.

RecyclerViewAdapter.java

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders> {
    private List<ItemObject> itemList;
    private Context context;
    public RecyclerViewAdapter(Context context, List<ItemObject> itemList) {
        this.itemList = itemList;
        this.context = context;
    }
    @Override
    public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
        View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null);
        RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView);
        return rcv;
    }
    @Override
    public void onBindViewHolder(RecyclerViewHolders holder, int position) {
        holder.songTitle.setText("Song Title: " + itemList.get(position).getSongTitle());
        holder.songYear.setText("Song Year: " + itemList.get(position).getSongYear());
        holder.songAuthor.setText("Song Author: " + itemList.get(position).getSongAuthor());
    }
    @Override
    public int getItemCount() {
        return this.itemList.size();
    }
}
We are also going to create a ViewHolder class. You can see that the Adapter class makes use of the ViewHolder pattern. Follow the steps we used to create the previous java file but in this case we will name our java file RecyclerViewHolders.java.
Open this class, copy and paste the code below inside this file.

RecyclerViewHolders.java

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
public class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
    public TextView songTitle;
    public TextView songYear;
    public TextView songAuthor;
    public RecyclerViewHolders(View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);
        songTitle = (TextView)itemView.findViewById(R.id.song_title);
        songYear = (TextView)itemView.findViewById(R.id.song_year);
        songAuthor = (TextView)itemView.findViewById(R.id.song_author);
    }
    @Override
    public void onClick(View view) {
    }
}
Next, we will create an entity class which will map the properties of the class to the object properties returned from the Json Object. You can see that the @SerializedName(“”) annotation was used. This is because the class properties have different names.
Follow the same steps above to create a new java file. We will name the file ItemObject.java. Once you have created this file, open the file, copy and paste the code below inside the file.

ItemObject.java

import com.google.gson.annotations.SerializedName;
public class ItemObject {
    @SerializedName("song_name")
    private String songTitle;
    @SerializedName("song_id")
    private String songYear;
    @SerializedName("artist_name")
    private String songAuthor;
    public ItemObject(String songTitle, String songYear, String songAuthor) {
        this.songTitle = songTitle;
        this.songYear = songYear;
        this.songAuthor = songAuthor;
    }
    public String getSongTitle() {
        return songTitle;
    }
    public String getSongYear() {
        return songYear;
    }
    public String getSongAuthor() {
        return songAuthor;
    }
}
To bring this all together, we will move to the MainActivity file. In this class, we will get an instance of the RecycleView, then, we will create an object of the Adapter and pass it as a parameter to the setAdapter method of the RecycleView class.
Remember that we will also create a Volley string request which will return the Json object that we will use to populate the RecycleView items.
The response Json string object is parse to Java plain object using the Gson library. You can see how all the codes come together.
Open the MainActivity.java file, copy and paste the following code inside the class.

MainActivity.java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends AppCompatActivity {
    private final String TAG = "MainActivity";
    private RecyclerView recyclerView;
    private LinearLayoutManager layoutManager;
    private RecyclerViewAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
        recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));
        layoutManager = new LinearLayoutManager(MainActivity.this);
        recyclerView.setLayoutManager(layoutManager);
        requestJsonObject();
    }
    private void requestJsonObject(){
        RequestQueue queue = Volley.newRequestQueue(this);
        String url ="http://toscanyacademy.com/blog/mp.php";
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        Log.d(TAG, "Response " + response);
                        GsonBuilder builder = new GsonBuilder();
                        Gson mGson = builder.create();
                        List<ItemObject> posts = new ArrayList<ItemObject>();
                        posts = Arrays.asList(mGson.fromJson(response, ItemObject[].class));
                        adapter = new RecyclerViewAdapter(MainActivity.this, posts);
                        recyclerView.setAdapter(adapter);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d(TAG, "Error " + error.getMessage());
            }
        });
        queue.add(stringRequest);
    }
}
In this code, if you look at this line
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));
If you look at the single line of code above, we are using it to add a line separator for the items in the RecycleView. If you like you can omit this part but if you want to add a line separator to the items of the RecycleView, then create a new java file and name it SimpleDividerItemDecoration.java.
Open the file, copy and paste the following code inside this file

SimpleDividerItemDecoration.java

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
    private Drawable mDivider;
    public SimpleDividerItemDecoration(Context context) {
        mDivider = ContextCompat.getDrawable(context, R.drawable.line_divider);
    }
    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        int left = parent.getPaddingLeft();
        int right = parent.getWidth() - parent.getPaddingRight();
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            int top = child.getBottom() + params.bottomMargin;
            int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
}
Also, we will add this drawable layout file in the drawable folder. Create a new Drawable layout file inside the Drawable folder and name it line_divider.xml. Copy and paste the following code inside the file.

line_divider.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size
        android:width="1dp"
        android:height="1dp" />
    <solid android:color="@color/colorDivide" />
</shape>
Run your application and see for yourself what we have just created.

Previous Post Next Post

Contact Form