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
Source Code
[emaillocker id=”4963″]
[/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.
Step | Description |
---|---|
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 –
- Builder class – The class that builds and configure an instance of retrofit. This instance will be used to send HTTP requests.
- Model class – This class represents JSON data in java.
- 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).
- onCreateViewHolder() method – Used to create an item view
- onBindViewHolder() method – Used to bind data for a view
- getItemCount() method – Gets the total item in list.
- 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.
You must be logged in to post a comment.