Using Android Retrofit Library With RecyclerView in Kotlin

Hello Readers! In this tutorial, we will learn about how to use android retrofit library with recyclerView in kotlin. We will see how to make rest api calls using retrofit and show the json response in recyclerView.

We have already seen how to use Volley library to make rest api calls. Retrofit library is definitely better than volley in terms of ease of use, performance and other things.

Android Retrofit Library is type safe HTTP client for android and java, developed by Square Inc., and uses OkHttp library for HTTP requests. This library makes developers life easy to handle JSON requests via REST based web service. You can make GET, POST, PUT, DELETE or PATCH requests using this library. Generally, GSon is used as converter for data serialization. However, you can add custom converters too for XML or other protocols.

So, in this post, we will learn about how to use android retrofit library with RecyclerView in kotlin.

As we already know, recyclerView is advanced and flexible version of ListView. It is used to show large data set. As the name suggests, RecyclerView reuses item’s view by recycling it in the data list.

Output

Tutorialwing Android Retrofit Library With RecyclerView Using Kotlin Output
Retrofit Library Using RecyclerView

Source Code

[emaillocker id=”4963″]

Retrofit Library Source Code

[/emaillocker]

Prerequisite

  • You should have a basic knowledge of android application folder structures, debugging and running application.

Getting Started

Now, You will see how to use android retrofit library with recyclerView in android application to make HTTP calls. 

In this application, You will use apis provided at StackExchange (https://api.stackexchange.com/docs/search). Many options are available there. For example, you can check questions based on tag, apply indexing in it, apply sorting in it, get questions within provided date range etc. 

Check out different available options at – https://api.stackexchange.com/docs/search

In this post, your target is to fetch questions tagged with android. The complete url will be 

https://api.stackexchange.com/2.2/search?order=desc&sort=activity&tagged=android&site=stackoverflow

At first, we will create an android project. Then, we will setup retrofit library in the project. After that, we will make a HTTP request using retrofit library. Then, we will create a list of items using JSON response got after HTTP requests.

1. Creating New Project in Kotlin

Follow steps below to create new project. Please ignore the steps if you have already created the project.

StepDescription
1.Open Android Studio.
2.Go to File => New => New Project. Then, select Empty Activity => click next.
3.Write Name as RetrofitLibrary. Then, select Kotlin as Language. After that, select Minimum API level you need. However, we have selected 21 as minimum SDK. Then, click finish button.
5.You will get a newly created project successfully if you have followed steps properly.

Now, you have a new android application (i.e. RetrofitLibrary)

1.2. Add Gradle For Retrofit And Gson

Since we are going to use android retrofit library with recyclerView in this application, we need to add retrofit in our application. So, let’s add gradle for retrofit library and gson converter in app/build.gradle file.

implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

After adding above lines, sync your project. That’s it. Your application is ready to use retrofit library now.
Note – We will soon add gradle for recyclerView in this application.

Do not want to use findViewById()?

We are using kotlin extension in the project to avoid using findViewById(). If you want so, you need to add apply plugin: ‘kotlin-android-extensions’ in app/build.gradle file.

Note – If you have selected kotlin as Language while creating project, you do not need to write anything. It’s already there.

1.3 Permission in Manifest File

Since your application needs access to internet to send HTTP requests, add internet permissions in main/AndroidManifest.xml file. 

You can add below line to get internet permission in main/AndroidManifest.xml file in your android application – 

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

1.4 Using Retrofit library in Application

You need three classes to use retrofit library in your application. They are – 

  1. Builder class  – The class that builds and configure an instance of retrofit. This instance will be used to send HTTP requests. 
  2. Model class – This class represents JSON data in java. 
  3. APIService class – This class represents possible operations (GET, PUT, PATCH, DELETE, POST) in apis.

Now, we will create all of the above mentioned classes one by one.

It’s always a better idea to modularise the application as per functions. So, create three folders rest, model and activity in main/java/com.example.retrofitlibrary package. Then, move MainActivity.java file into main/java/com.example.retrofitlibrary/activity folder. Don’t forget to update the activity name in AndroidManifest.xml file. (Note – you just need to update activity name as android:name=”.activity.MainActivity”)

As we already know, we are using apis provided by StackExchange in this application. You can check http://api.stackexchange.com/docs/questions for more detail.

For this post, we are interested in all the questions in stackExchange that have been tagged as android. So, Url that we will be requesting is –

//Base url
https://api.stackexchange.com

//End url
/2.2/questions?order=desc&sort=creation&site=stackoverflow

Now, we will create all the necessary classes for retrofit library one by one.

1.4.1 Creating Builder class

As discussed above, Builder class contains instance of retrofit. You can configure and build instance  of retrofit in this class. All the calls are made using instance of retrofit. Whenever we create an instance of RestClient, we provide a base url with it. In our case, base url is –

https://api.stackexchange.com


Now, create a new kotlin file, RestClient.kt, in com.example.retrofitlibrary/rest folder. Then, add below code into it.

package com.example.retrofitlibrary.rest

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RestClient {

    private val BASE_URL = "https://api.stackexchange.com"
    private var mRetrofit: Retrofit? = null


    val client: Retrofit
        get() {
            if (mRetrofit == null) {
                mRetrofit = Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .build()
            }
            return this.mRetrofit!!
        }
}


Note that we are creating only one instance of Retrofit. Whenever get method is called, it checks if there is already an instance of retrofit or not. If not, a new instance is created. Otherwise, old instance is returned. BASE_URL represents base url of all the requests. In this tutorial, it is https://api.stackexchange.com.

1.4.2 Creating Model Class

Now, you need to create a model class. Model class is representation of JSON in Java. In our scenario, we will be sending request at https://api.stackexchange.com/2.2/search?order=desc&sort=activity&tagged=android&site=stackoverflow

You can check the json data at this url. This JSON contains list of all the questions tagged as android.

Note – you can view json present at https://api.stackexchange.com/2.2/search?order=desc&sort=activity&tagged=android&site=stackoverflow using Online JSON Viewer . You just to need to copy and paste the json present at url in JSON Viewer.

For the sake of simplicity of this tutorial, we are interested in only title and link fields for each object in the list. So, we will be creating two model classes –

  • Question – Represents a question object in list.
  • QuestionList – Represents questions list

So, create a new file, Question.kt, in com.example.retrofitlibrary/model folder. Then, add below code into it –

package com.example.retrofitlibrary.model

//This class maps the json keys to the object
class Question {

    val title: String? = null
    val link: String? = null
}

Now, create another file,QuestionList.kt, in com.example.retrofitlibrary/model folder. Then, add below code into it –

package com.example.retrofitlibrary.model

class QuestionList {
    val items: List<Question>? = null
    val has_more: Boolean? = null
    val quota_max: Number? = null
    val quota_remaining: Number? = null
}

1.4.3 Creating ApiService

Now, we will create an apiService that will be used with android retrofit library with recyclerView to make an api calls.
As we have already discussed, we are interested in all the questions that have been tagged as android. So, end url will be –

/2.2/questions?order=desc&sort=creation&site=stackoverflow

So, create a new file, APIService.kt, in com.example.retrofitlibrary/rest folder. Then, add below code into it.

package com.example.retrofitlibrary.rest

import com.example.retrofitlibrary.model.QuestionList
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Query

interface APIService {
    @GET("/2.2/questions?order=desc&sort=creation&site=stackoverflow")    //End Url
    fun fetchQuestions(@Query("tagged") tags: String): Call<QuestionList>
}

@GET(“end Url”)  – Represents GET request with given end url. Remember we have already defined base url in RestClient.kt class while building an instance of retrofit.

Call<QuestionList> – This represents an object of QuestionList that will be returned by the request. 

fetchQuestions() – Call this method to send request to server. It accepts parameter as well. As of now, it accepts only string value as query parameter.

Here, we have created an apiService fetchQuestions that we will be called to fetch questions. This method also accepts a tag as query parameter. So, we will pass android as query while using fetchQuestion() method.

Now, our retrofit setup is done in the project. So, we will see how to use this retrofit library with recyclerView in our application

1.5 Make API calls using Retrofit library

Since our model, builder and APIService classes are ready, we will now see how to make rest api calls using retrofit library.

As we already know, we can make GET, POST, PUT, DELETE or PATCH using this library. We will see a sample GET request now –

        var mApiService: APIService = RestClient.client.create(APIService::class.java);
        val call = mApiService.fetchQuestions("android");
        call.enqueue(object : Callback<QuestionList> {

            override fun onResponse(call: Call<QuestionList>, response: Response<QuestionList>) {
                 // Write code to perform actions when request succeeds.
            }

            override fun onFailure(call: Call<QuestionList>, t: Throwable) {
                // Write code perform actions when request fails...
            }
        })

Here, we have used our model class, apiService class and builder class to make HTTP GET request. Similarly, you can define POST, PUT or PATCH request.

2.0 Using Android Retrofit Library With RecyclerView

Since everything is setup, now we will make a HTTP call using retrofit library and show the response in recyclerView.
So, let’s add gradle for recyclerView in app/build.gradle file.

implementation 'com.android.support:recyclerview-v7:27.1.1'

Then, click on sync button shown at top-right of the editor.

2.1 Add Android RecyclerView into xml file

Add recyclerView widget into res/layout/activity_main.xml file. So, add below lines of code into res/layout/activity_main.xml file –

<?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="@dimen/padding_default">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/listRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

</RelativeLayout>

In activity_main.xml file, we have added only android.support.v7.widget.RecyclerView widget. Now, we will define a layout for each item in recyclerView. Then, we will create an adapter that can be used to provide data to recyclerView.

2.2 Define Layout For Single Item

To use android retrofit library with recyclerView, we must define a layout for single item in recyclerView. So, create a new xml file, question_item.xml, in res/layout folder. Then, add below code into it.

<?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="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/positionNumber"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold" />

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

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

    <View
        android:layout_width="match_parent"
        android:layout_height="@dimen/line_height"
        android:layout_marginBottom="@dimen/margin_small"
        android:layout_marginTop="@dimen/margin_small"
        android:background="@android:color/darker_gray" />

</LinearLayout>

2.3 Create Adapter For RecyclerView

Till now, we have done some basic setups to use android retrofit library with recyclerView. Now, we will create an adapter that provides data to the recyclerView.

Create a new folder, adapter, in src/com.example.retrofitlibrary folder. Then, create a new kotlin file, ListAdapter.kt, in this new folder (i.e. src/com.example.retrofitlibrary/adapter folder). Then, add below code into it.

package com.example.retrofitlibrary.adapter

import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast

import com.example.retrofitlibrary.R
import com.example.retrofitlibrary.model.Question
import kotlinx.android.synthetic.main.question_item.view.*

class ListAdapter(private val context: Context, private val mQuestions: List<Question>, private val mRowLayout: Int) : RecyclerView.Adapter<ListAdapter.QuestionViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QuestionViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(mRowLayout, parent, false)
        return QuestionViewHolder(view)
    }

    override fun onBindViewHolder(holder: QuestionViewHolder, position: Int) {
        holder.positionNumber?.text = context.resources.getString(R.string.question_num, position + 1)
        holder.title?.text = context.resources.getString(R.string.ques_title, mQuestions[position].title)
        holder.link?.text = context.resources.getString(R.string.ques_link, mQuestions[position].link)

        holder.containerView.setOnClickListener {
            Toast.makeText(context, "Clicked on: " + holder.title.text, Toast.LENGTH_SHORT).show();
        }
    }

    override fun getItemCount(): Int {
        return mQuestions.size
    }

    class QuestionViewHolder(val containerView: View) : RecyclerView.ViewHolder(containerView) {
        val positionNumber = containerView.positionNumber;
        val title = containerView.title;
        val link = containerView.link;
    }
}

In ListAdapter.kt file, we have defined three methods(onCreateViewHolder(), onBindViewHolder() and getItemCount()) and a class (QuestionViewHolder).

  1. onCreateViewHolder() method – Used to create an item view
  2. onBindViewHolder() method – Used to bind data for a view
  3. getItemCount() method – Gets the total item in list.
  4. QuestionViewHolder class – represents viewHolder for an item.

2.4 Make HTTP request using Retrofit Library

Till now, we have successfully created adapter, apiService, an instance of model class, ui for single item in recyclerView. Now, we will see how to make a HTTP request using retrofit library.
We can send GET, PUT, POST, PATCH or DELETE requests using retrofit library. Now, we will make HTTP request request using retrofit library in this android application.

We will make a GET request using retrofit that fetches all the questions with tag android.

We can make a GET request as below –

       var mApiService: APIService = RestClient.client.create(APIService::class.java);
        val call = mApiService.fetchQuestions("android");
        call.enqueue(object : Callback<QuestionList> {

            override fun onResponse(call: Call<QuestionList>, response: Response<QuestionList>) {
                 // Write code to perform actions when request succeeds.
            }

            override fun onFailure(call: Call<QuestionList>, t: Throwable) {
                // Write code perform actions when request fails...
            }
        })

Finally, MainActivity.kt file will be like –

package com.example.retrofitlibrary.activity

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.example.retrofitlibrary.R
import com.example.retrofitlibrary.adapter.ListAdapter
import com.example.retrofitlibrary.model.Question
import com.example.retrofitlibrary.model.QuestionList
import com.example.retrofitlibrary.rest.APIService
import com.example.retrofitlibrary.rest.RestClient
import kotlinx.android.synthetic.main.activity_main.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.util.*

class MainActivity : AppCompatActivity() {

    private var mApiService: APIService? = null

    private var mAdapter: ListAdapter?= null;
    private var mQuestions: MutableList<Question> = ArrayList()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mApiService = RestClient.client.create(APIService::class.java)

        listRecyclerView!!.layoutManager = LinearLayoutManager(this)

        mAdapter = ListAdapter(this, mQuestions, R.layout.question_item)
        listRecyclerView!!.adapter = mAdapter

        fetchQuetionList()
    }

    private fun fetchQuetionList() {
        val call = mApiService!!.fetchQuestions("android");
        call.enqueue(object : Callback<QuestionList> {

            override fun onResponse(call: Call<QuestionList>, response: Response<QuestionList>) {

                Log.d(TAG, "Total Questions: " + response.body()!!.items!!.size)
                val questions = response.body()
                if (questions != null) {
                    mQuestions.addAll(questions.items!!)
                    mAdapter!!.notifyDataSetChanged()
                }
            }

            override fun onFailure(call: Call<QuestionList>, t: Throwable) {
                Log.e(TAG, "Got error : " + t.localizedMessage)
            }
        })
    }

    companion object {
        private val TAG = MainActivity::class.java.simpleName
    }
}

Now, run the application. You will get output as shown in output section.

That’s end of tutorial on using android retrofit library with recyclerView in kotlin. Let us know if you have any question in comment section below.

Leave a Reply