How to integrate Rest Api using Retrofit in Android using Kotlin.
Last updated Jan 11, 2022 In this Android example tutorial, you will see how to integrate Rest Api using Retrofit library in Android using Kotlin. Retrofit is a Square type-safe REST client for Android, Java, and Kotlin. With OkHttp, the library offers a strong foundation for authenticating and communicating with APIs, as well as sending network requests. This module simplifies the process of getting JSON or XML data from a web API.
Integrate Retrofit in Android
Step 1. Create a new Project in android studio.
Go to File > New > New Project > Empty Activity > Next > Enter Name > Select Language Kotlin > Finish.
|
Step 2. Open your project and add dependencies into app level build.gradle ( Module:app) file. Here we adds Gson,RecyclerView, and Retrofit libraries
implementation 'androidx.recyclerview:recyclerview:1.2.1'
// Retrofit Dependency
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
|
Step 3. Go to AndroidManifest.xml file and add the permission of Internet and Access_Network_State:"
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
Step 4. Create a new Interface file and add the following
app > java > package name > right-click > New > Kotlin class/file (ApiInterface) > enter name > OK
|
This file contains the endpoint of api and the Http methods of api (Get, Post etc..)
interface ApiInterface {
@GET("quotes")
fun getQuotes(): Call>
}
|
Step 5. Create a new file for ApiClient and add the following:
This file is used for create client for api
class APIClient {
fun getRetrofitClient(): Retrofit {
val gson = GsonBuilder().setLenient().create()
return Retrofit.Builder().baseUrl("https://www.breakingbadapi.com/api/")
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
}
}
|
Step 6. Go to activity_main.xml file and add the following xml code:
<LinearLayout 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=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recyclerView">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
|
Step 7. Create a new layout resource file and add the following code
app > res > layout > new > layout resource file > enter name (layout_items) > ok
|
The xml code:
<?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:padding="10dp"
android:background="#E7E4EF"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="8sp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/quoteText"
android:textSize="17sp"
android:textStyle="bold"
android:textColor="@color/black"
android:text="I am not in danger, Skyler. I am the danger!"></TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="2"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/quoteSeries"
android:layout_weight="1"
android:textColor="@color/black"
android:textStyle="italic"
android:text="Walter White"></TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/quoteAuthor"
android:layout_weight="1"
android:gravity="end"
android:textStyle="italic"
android:text="Breaking Bad"></TextView>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
|
Step 8. Create a new Kotlin class for model
app > java > package name > right-click > New > Kotlin class/file (DataModel) > enter name > OK |
This file will hold the information of every item which you want to show in your RecyclerView.
class DataModel(quote_id: Int?, quote: String?, author: String?, series: String?) {
var quote_id: Int? = null
var quote: String? = null
var author: String? = null
var series: String? = null
}
|
Step 9. Create a adapter class
app > java > package name > right-click > New > Kotlin class/file (RecyclerAdapter) > enter name > ok
|
This class contains some important functions to work with the RecyclerView these are as follows:
- onCreateViewHolder(): This function sets the views to display the items.
- onBindViewHolder(): This function is used to bind the list items to our widgets such as TextView, ImageView, etc.
- getItemCount(): It returns the count of items present in the list.
Code:
class RecyclerAdapter(private val dataList: List) : RecyclerView.Adapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.layout_items, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
val recyclerModel = dataList[position]
// Text set to the TextView widget
holder.quoteText.text = recyclerModel.quote
holder.author.text = recyclerModel.author
holder.series.text = recyclerModel.series
}
override fun getItemCount(): Int {
return dataList.size
}
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
val quoteText: TextView = itemView.findViewById(R.id.quoteText)
val author: TextView = itemView.findViewById(R.id.quoteAuthor)
val series: TextView = itemView.findViewById(R.id.quoteSeries)
}
}
|
Step 10. Go to MainActivity.kt file and add the following code
Initialize the recyclerView widget below setContentView(R.layout.activity_main) and create a method to fetch data.
class MainActivity : AppCompatActivity() {
var quotesList = ArrayList()
lateinit var rv: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rv = findViewById(R.id.recyclerView)
getQuote()
}
private fun getQuote(){
val client = APIClient().getRetrofitClient().create(ApiInterface::class.java)
client.getQuotes().enqueue(object : Callback> {
override fun onResponse(
call: Call>,
response: Response>
) {
// Used for inserting data in arraylist of type DataModel
quotesList = response.body() as ArrayList
val adapter = RecyclerAdapter(quotesList)
// For showing data list vertically
rv.layoutManager = LinearLayoutManager(this@MainActivity)
rv.adapter = adapter
}
override fun onFailure(call: Call>, t: Throwable) {
// Write a code for failure
}
})
}
}
|
Step 11. Now run the app in your emulator, and get the following output.
Complete source code of Retrofit Kotlin with Example:
activity_main.xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recyclerView">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
|
MainActivity.kt file
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class MainActivity : AppCompatActivity() {
var quotesList = ArrayList()
lateinit var rv: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rv = findViewById(R.id.recyclerView)
getQuote()
}
private fun getQuote(){
val client = APIClient().getRetrofitClient().create(ApiInterface::class.java)
client.getQuotes().enqueue(object : Callback> {
override fun onResponse(
call: Call>,
response: Response>
) {
// Used for inserting data in arraylist of type DataModel
quotesList = response.body() as ArrayList
val adapter = RecyclerAdapter(quotesList)
// For showing data list vertically
rv.layoutManager = LinearLayoutManager(this@MainActivity)
rv.adapter = adapter
}
override fun onFailure(call: Call>, t: Throwable) {
// Write a code for failure
}
})
}
}
|
APIClient.kt file
import com.google.gson.GsonBuilder
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class APIClient {
fun getRetrofitClient(): Retrofit {
val gson = GsonBuilder().setLenient().create()
return Retrofit.Builder().baseUrl("https://www.breakingbadapi.com/api/")
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
}
}
|
ApiInterface.kt file
import retrofit2.Call
import retrofit2.http.GET
interface ApiInterface {
@GET("quotes")
fun getQuotes(): Call>
}
|
layout_items.xml file
<?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:padding="10dp"
android:background="#E7E4EF"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="8sp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/quoteText"
android:textSize="17sp"
android:textStyle="bold"
android:textColor="@color/black"
android:text="I am not in danger, Skyler. I am the danger!"></TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="2"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/quoteSeries"
android:layout_weight="1"
android:textColor="@color/black"
android:textStyle="italic"
android:text="Walter White"></TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/quoteAuthor"
android:layout_weight="1"
android:gravity="end"
android:textStyle="italic"
android:text="Breaking Bad"></TextView>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
|
DataModel.kt file
class DataModel(quote_id: Int?, quote: String?, author: String?, series: String?) {
var quote_id: Int? = null
var quote: String? = null
var author: String? = null
var series: String? = null
}
|
RecyclerAdapter.kt file
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class RecyclerAdapter(private val dataList: List) : RecyclerView.Adapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.layout_items, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
val recyclerModel = dataList[position]
// Text set to the TextView widget
holder.quoteText.text = recyclerModel.quote
holder.author.text = recyclerModel.author
holder.series.text = recyclerModel.series
}
override fun getItemCount(): Int {
return dataList.size
}
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
val quoteText: TextView = itemView.findViewById(R.id.quoteText)
val author: TextView = itemView.findViewById(R.id.quoteAuthor)
val series: TextView = itemView.findViewById(R.id.quoteSeries)
}
}
|
AndroidManifest.xml file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nishajain.retrofitkotlin">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.RetrofitKotlin">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
|
build.gradle(app) file
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.nishajain.retrofitkotlin"
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
}
|
Conclusion: In this article we have covered how to integrate Rest Api in Android using Retrofit with Kotlin code.