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.