Dedicated Server

Android Recyclerview with Cardview example : json parsing using retrofit

RecyclerView to fetch a list of cars from a json array



Following is the json array example that we are about to parse >> https://navneet7k.github.io/sample_array.json.

sample_array.json

[
  {
    "id": "1",
    "name": "Mercedes Benz",
    "desc": "Mercedes Benz is a global automobile marque and a division of the German company Daimler AG. The brand is known for luxury vehicles, buses, coaches, and lorries. The headquarters is in Stuttgart, Baden-Württemberg. The name first appeared in 1926 under Daimler-Benz."
  },
  {
    "id": "2",
    "name": "BMW",
    "desc": "BMW AG, originally an initialism for Bayerische Motoren Werke in German, or Bavarian Motor Works in English) is a German multinational company which currently produces luxury automobiles and motorcycles, and also produced aircraft engines until 1945."
  },
  {
    "id": "3",
    "name": "Bentley",
    "desc": "Bentley Motors Limited is a British manufacturer and marketer of luxury cars and SUVs—and a subsidiary of the Volkswagen Group since 1998."
  },
  {
    "id": "4",
    "name": "Mustang",
    "desc": "The Ford Mustang is an American car manufactured by Ford. It was originally based on the platform of the second generation North American Ford Falcon, a compact car."
  },
  {
    "id": "5",
    "name": "Aston Martin",
    "desc": "Aston Martin Lagonda Global Holdings plc is a British independent manufacturer of luxury sports cars and grand tourers. It was founded in 1913 by Lionel Martin and Robert Bamford."
  },
  {
    "id": "6",
    "name": "Lamborghini",
    "desc": "Automobili Lamborghini is an Italian brand and manufacturer of luxury sports cars and SUVs based in Sant'Agata Bolognese and tractors Lamborghini Trattori in Pieve di Cento, Italy. The company is owned by the Volkswagen Group through its subsidiary Audi."
  },
  {
    "id": "7",
    "name": "BMW",
    "desc": "BMW AG, originally an initialism for Bayerische Motoren Werke in German, or Bavarian Motor Works in English) is a German multinational company which currently produces luxury automobiles and motorcycles, and also produced aircraft engines until 1945."
  },
  {
    "id": "8",
    "name": "Bentley",
    "desc": "Bentley Motors Limited is a British manufacturer and marketer of luxury cars and SUVs—and a subsidiary of the Volkswagen Group since 1998."
  },
  {
    "id": "9",
    "name": "Mustang",
    "desc": "The Ford Mustang is an American car manufactured by Ford. It was originally based on the platform of the second generation North American Ford Falcon, a compact car."
  },
  {
    "id": "10",
    "name": "Aston Martin",
    "desc": "Aston Martin Lagonda Global Holdings plc is a British independent manufacturer of luxury sports cars and grand tourers. It was founded in 1913 by Lionel Martin and Robert Bamford."
  },
  {
    "id": "11",
    "name": "Lamborghini",
    "desc": "Automobili Lamborghini is an Italian brand and manufacturer of luxury sports cars and SUVs based in Sant'Agata Bolognese and tractors Lamborghini Trattori in Pieve di Cento, Italy. The company is owned by the Volkswagen Group through its subsidiary Audi."
  },
  {
    "id": "12",
    "name": "BMW",
    "desc": "BMW AG, originally an initialism for Bayerische Motoren Werke in German, or Bavarian Motor Works in English) is a German multinational company which currently produces luxury automobiles and motorcycles, and also produced aircraft engines until 1945."
  },
  {
    "id": "13",
    "name": "Bentley",
    "desc": "Bentley Motors Limited is a British manufacturer and marketer of luxury cars and SUVs—and a subsidiary of the Volkswagen Group since 1998."
  },
  {
    "id": "14",
    "name": "Mustang",
    "desc": "The Ford Mustang is an American car manufactured by Ford. It was originally based on the platform of the second generation North American Ford Falcon, a compact car."
  },
  {
    "id": "15",
    "name": "Aston Martin",
    "desc": "Aston Martin Lagonda Global Holdings plc is a British independent manufacturer of luxury sports cars and grand tourers. It was founded in 1913 by Lionel Martin and Robert Bamford."
  },
  {
    "id": "16",
    "name": "Lamborghini",
    "desc": "Automobili Lamborghini is an Italian brand and manufacturer of luxury sports cars and SUVs based in Sant'Agata Bolognese and tractors Lamborghini Trattori in Pieve di Cento, Italy. The company is owned by the Volkswagen Group through its subsidiary Audi."
  }
]


Now let us jump into some code, go to your app level build.gradle file and add all the necessary dependencies like shown below

implementation 'com.android.support:cardview-v7:28.0.0' 
implementation 'com.android.support:design:28.0.0' 
implementation 'com.squareup.retrofit2:retrofit:2.0.0-beta4' 
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
app level build.gradle file


First of all, generate the model class like shown below(you may create it manually also).

1) Automatic model class/pojo class generation using http://www.jsonschema2pojo.org/

You can make use of jsonschema2pojo to covert json to java object online. This is a really effective tool which even supports various annotation types like jackson, gson, moshi etc.
Specify Target language as Java, Source Type as JSON and annotation style as Gson
  • Now click preview and copy the generated java files
Now copy the contents of the class and add it in android studio project

copy the contents of the java class generated from jsonschema2pojo and rename it to CarModel.java as shown below

CarModel.java

public class CarModel {
    @SerializedName("id")
    @Expose
    private String id;
    @SerializedName("name")
    @Expose
    private String name;
    @SerializedName("desc")
    @Expose
    private String desc;

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}

Now that you have generated the required model class, you will have to create an adapter for your recyclerview, which inflates the layout(item_layout.xml) for each recyclerview item. We will be passing the array fetched from the json into this adapter as an arraylist through its constructor.

DataAdapter.java

public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
    private ArrayList<CarModel> articles=new ArrayList<>();
    private Context context;

    public DataAdapter(ArrayList<CarModel> articles, Context context) {
        this.context=context;
        this.articles=articles;
    }

    @Override
    public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_layout, viewGroup, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(DataAdapter.ViewHolder viewHolder, final int i) {

        final String car_name=articles.get(i).getName();
        final String car_desc=articles.get(i).getDesc();

        viewHolder.car_name.setText(car_name);
        viewHolder.car_desc.setText(car_desc);

    }

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

    public class ViewHolder extends RecyclerView.ViewHolder{
        private TextView car_name,car_desc;


        public ViewHolder(View view) {
            super(view);
            car_name = (TextView)view.findViewById(R.id.car_name);
            car_desc = (TextView)view.findViewById(R.id.car_desc);
        }
    }

}

Since we are parsing a json array example, we can parse it as a list like this List<CarModel>. So our response type will be of type List<CarModel>. Now create your retrofit instance by passing it with GsonConverterFactory. We will need gson since it will help you convert our json response into java model easily. Below, in onResponse you can see that we have fetched the reponse as a list and then passed to an arraylist. Further we have passed this arraylist to the adapter using the constructor like this

dataAdapter=new DataAdapter(carModels,MainActivity.this);

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private DataAdapter dataAdapter;
    private ArrayList<CarModel> carModels=new ArrayList<>();
    private RecyclerView mRecyclerView;
    private ProgressBar mProgressBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mProgressBar=(ProgressBar)findViewById(R.id.progress_bar);
        mProgressBar.setVisibility(View.VISIBLE);
        mRecyclerView=(RecyclerView)findViewById(R.id.cars_list);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        parseJson();
    }

    private void parseJson() {
        
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://navneet7k.github.io/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        RequestInterface request = retrofit.create(RequestInterface.class);
        Call<List<CarModel>> call1=request.getJson();
        call1.enqueue(new Callback<List<CarModel>>() {
            @Override
            public void onResponse(Call<List<CarModel>> call, Response<List<CarModel>> response) {
                mProgressBar.setVisibility(View.GONE);
                if (response.isSuccessful() && response.body()!=null) {
                    carModels = new ArrayList<>(response.body());
                    dataAdapter=new DataAdapter(carModels,MainActivity.this);
                    mRecyclerView.setAdapter(dataAdapter);
                }
            }

            @Override
            public void onFailure(Call<List<CarModel>> call, Throwable t) {
                mProgressBar.setVisibility(View.GONE);
                Toast.makeText(MainActivity.this,"Oops! Something went wrong!",Toast.LENGTH_SHORT).show();
            }

        });
    }

}

As shown above, after initialising the adapter, we set the adapter( dataAdapter ) to our recyclerview(mRecyclerView) like shown below.

mRecyclerView.setAdapter(dataAdapter);

Below is the interface for our network call to the endpoint.

RequestInterface.java

interface RequestInterface {
    @GET("sample_array.json")
    Call<List<CarModel>> getJson();
}


Below in the MainActivity's layout file(activity_main.xml
), we are adding the recyclerview widget.

activity_main.xml

<?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/cars_list"
        tools:listitem="@layout/item_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <ProgressBar
        android:visibility="gone"
        android:id="@+id/progress_bar"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>


Further each recyclerview item's design will be as follows, we are inflating the following layout in the adapter class(DataAdapter.java) which takes care of handling each item in the recyclerview. Since each item in the recyclerview is reused during scroll to generate new items, onBindViewHolder method in DataAdapter.java gets called continuously to generate each item.

item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="5dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

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

    <TextView
        android:id="@+id/car_desc"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.CardView>

The android.support.v7.widget.CardView used in above layout gives a cards like finish to the recyclerview items, it gives a cool material finish to the entire recyclerview. It would look something like this >>

cardview example


Your resulting directory structure will be similar to the following

add all the java files within your package folder in 'src' directory and add the layout files in layout folder inside 'res' directory
Thats it! try running the project and you could see an output like the one shown in the GIF at the beginning of the tutorial

Download full source code here


10 comments:

  1. Many Manuals about Retrofit suck and doesnt work! You Project great and well done. Thanks!

    ReplyDelete
  2. Many manuals about retrofit on the Internet do not work even with source code. You Example great! Thanks!

    ReplyDelete
    Replies
    1. glad to know that it helped you, thanks for sharing feedback

      Delete
  3. thanks bro.I will try. I wanted this to show a POC to a client . I am a java developer but dont know android

    ReplyDelete
  4. Thank you so much, this code is very useful and easy to understand.

    ReplyDelete
  5. I really do appreciate this article, it was just what I needed to carry out my project.

    Thank you.

    ReplyDelete