NoobsPlanet

Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics, posts and unlimited download to our resources, as well as connect with other members through your own private inbox!

Android RecyclerView - Fetching json data from server.

noobsplanet

Active member
Staff member
Administrator
Moderator
863
864
865


In this tutorial we'll be using RecyclerView, CardView, Picasso and Volley to make network connection to fetch data from server and set into RecycerView. CardView is used for making a beautiful list and Picasso is used for setting image resource from internet. We need to add dependency for RecycerView, CardView and Volley. Insert the following code inside dependency on your build.gradle project and syncronize the project.
build.gradle:
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.volley:volley:1.1.1'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.android.support:cardview-v7:28.0.0'
Now, create a RecyclerView on your xml, I've named it as activity_main.xml on res directory, which I will be calling from MainActivity.java.

activity_main.xml:
<android.support.constraint.ConstraintLayout 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="wrap_content"
       android:layout_height="match_parent">
   </android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>
Now, let's us create a pattern for displaying a item on RecyclerView with RelativeLayout as parent for CardView. The CardView, card_view:cardCornerRadius="4dp" property will make the card corner round, you may try changing value for more noticeable. And the card_view:cardUseCompatPadding="true" will make a auto padding between the list. setting is to false will remove the spaces between the list. The CardView could represent the following three things :
  • ImageButton for displaying right arrow at the end of list.
  • ImageView to display a user image.
  • TextView for displaying user's first name and last name.
  • TextView for displaying a user's id.
adapter_layout.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="wrap_content"
    android:orientation="vertical">

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        card_view:cardCornerRadius="4dp"
        card_view:cardUseCompatPadding="true">

        <ImageButton
            android:layout_width="35dp"
            android:layout_height="35dp"
            android:tint="@color/cardview_dark_background"
            android:background="@null"
            android:rotation="90"
            android:layout_gravity="center_vertical|end"
            android:src="@android:drawable/arrow_up_float"/>

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

            <ImageView
                android:id="@+id/avatar"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginRight="16dp"
                android:scaleType="fitCenter" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/firstname_lastname"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:textAppearanceMedium" />

                <TextView
                    android:id="@+id/id"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />

            </LinearLayout>
        </LinearLayout>

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

</RelativeLayout>
Just like a ListView, a RecyclerView needs an adapter to access data. But before we create an adapter, let us create a getter and setter pojo class which we can set the data and can retrieve it later. You can generate getter and setter by Right Click inside class and select Generate > Getter and Setter or for keyboard Alt+ Insert > Generate Getter and Setter. I named this class as RecyclerViewData.java

RecyclerViewData.java:
public class RecyclerViewData {
    private int id;
    private String firstname;
    private String lastname;
    private String avatar;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }
}
Now, we'll create an Adapter class named as RVAdapter.java which extends ViewHolder Class, so you need to define a custom class which extends RecyclerView.ViewHolder. See the comment on code to understand.
RVAdapter.java:
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.squareup.picasso.Picasso;

import java.util.List;

//Adapter extends Custom View holder class defined on the bottom of this code.
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.RVHOLDER> {
    List<RecyclerViewData> recyclerViewDataList;
    Context mContext;

// Constructor with List and Context which we'll pass from RecyclerView Activity after a connection to Volley. And application context for the listener that we'll implement this later.
    public RVAdapter(List<RecyclerViewData> recyclerViewDataList, Context mContext) {
        this.recyclerViewDataList = recyclerViewDataList;
        this.mContext = mContext;
    }

   // Override the method onCreateViewHolder, which will call the custom view holder that needs to be initialized. We specify the layout that each item to be used, so we can achieve this using Layout Inflator to inflate the layout and passing the output to constructor of custom ViewHolder.
    @NonNull
    @Override
    public RVHOLDER onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.adapter_layout, viewGroup, false);
        RVHOLDER rvholder = new RVHOLDER(itemView);
        return rvholder;
    }


   //onBindViewHolder is for specifying the each item of RecyclerView. This is very similar to getView() method on ListView. In our example, this is where you need to set the user's id, name and image.
    @Override
    public void onBindViewHolder(@NonNull RVHOLDER rvholder, int i) {
        rvholder.id.setText("User id is "+recyclerViewDataList.get(i).getId());
        rvholder.first_name.setText(recyclerViewDataList.get(i).getFirstname() + " " + recyclerViewDataList.get(i).getLastname());
        Picasso.get().load(recyclerViewDataList.get(i).getAvatar()).into(rvholder.avatar);
    }

  //We need to return the size for RecyclerView as how long a RecyclerView is, Our data is in list so passing data.size() will return the number as long as we have.
    @Override
    public int getItemCount() {
        return recyclerViewDataList.size();
    }

//This is CustomView holder that we had discuss it earlier above and inflated it in onCreateView() method. This constructor links with the xml to set the data, which we set into onBindViewHolder().
    class RVHOLDER extends RecyclerView.ViewHolder {
        TextView id;
        private TextView first_name;
        private ImageView avatar;

        public RVHOLDER(@NonNull View itemView) {
            super(itemView);
            id = itemView.findViewById(R.id.id);
            first_name = itemView.findViewById(R.id.firstname_lastname);
            avatar = itemView.findViewById(R.id.avatar);
        }
    }
}
Finally, MainActivity.java which will request a data using Volley using Singleton pattern after a view is created. Then after getting response from server, we'll set a user information to RecyclerViewData and passing object of RecyerViewData to List<RecyclerViewData>, which we need to pass to adapter.

MainActivity.java:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    List<RecyclerViewData> recyclerViewDataList;
    RecyclerView recyclerView;
    private RVAdapter rvAdapter;
    private static final String TAG="apple";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setTitle("Employee List");

        recyclerViewDataList=new ArrayList<>();

        recyclerView=findViewById(R.id.recyclerView);

        LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);
        MakeVolleyConnection();
   
    }

private void MakeVolleyConnection() {
    recyclerViewDataList = new ArrayList<>();
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET,
            "https://reqres.in/api/users?page=1", null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            try {
                if (swipeRefreshLayout.isRefreshing()){
                    swipeRefreshLayout.setRefreshing(false);
                }
                JSONArray dataArray = response.getJSONArray("data");
                for (int i = 0; i < dataArray.length(); i++) {
                    JSONObject userData = dataArray.getJSONObject(i);
                    RecyclerViewData recyclerViewData = new RecyclerViewData();
                    recyclerViewData.setId(userData.getInt("id"));
                    recyclerViewData.setFirstname(userData.getString("first_name"));
                    recyclerViewData.setLastname(userData.getString("last_name"));
                    recyclerViewData.setAvatar(userData.getString("avatar"));
                    recyclerViewDataList.add(recyclerViewData);

                }
                rvAdapter = new RVAdapter(recyclerViewDataList, MainActivity.this);
                recyclerView.setAdapter(rvAdapter);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            if (swipeRefreshLayout.isRefreshing()){
                swipeRefreshLayout.setRefreshing(false);
            }
            Toast.makeText(MainActivity.this, ""+error.networkResponse,Toast.LENGTH_SHORT).show();
        }
    });

    MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest);
   }
}
Don't forget to add Internet Permission to Manifest.xml
Manifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
Compile and Run
Do you use test this program on Android version 9.0 (pie) or higher? If yes, you'll need to add this on your manifest.xml. If you've any questions or having trouble running it then feel free to comment below, attach the code or project file which will be helpful to us to identify problems. :geek:
 
Last edited:
Top