RETROFIT + KOTLIN + JETPACK

Retrofit is a REST Client library (Network Service). Its use in ANDROID application and JAVA to create an HTTP request and also to process the HTTP response from a REST API.

RETROFIT + KOTLIN + JETPACK

RETROFIT + KOTLIN + JETPACK

Please download project and sample here.  RetrofitKotlin

Retrofit is a type-safe HTTP client for Android and Java – developed by Square. 

Benifits :

A. Retrofit turns your HTTP API into a Java interface.

B. There are five built-in annotations: GETPOSTPUTDELETE, and HEAD

 

implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
// gson convertor
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'

 

Let's create a sample application which written in kotlin.

We hit an API with help of RETROFIT serivices and display in RECYCLEVIEW.

 

----------------------------------------------------------------

Creating a sample project in android studio

 

1. Creating a sample Project in android studio : 

Create a sample project from android studio. to create a sample project please go to below steps:

A. Setup Android Studio : https://developer.android.com/studio

B. File  >> New  >> New Project >> A popup will come then select an 'Empty Activity'.

C. Select Project name, package name, SDK Version and Language Kotlin.

 

2.  You just need to select a module or a folder in the Project navigator and select 

Code -> Convert Java file to Kotlin file:

 

3. Open project app -> res -> change resource values file like strings, color, styles.

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#008577</color>
    <color name="colorPrimaryDark">#00574B</color>
    <color name="colorAccent">#D81B60</color>
    <color name="black">#000000</color>
</resources>

strings.xml

<resources>
    <string name="app_name">RetrofitKotlin</string>
</resources>

styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

 

4.  Go to  app project gradle file and  add dependencies  for retrofit,  glide, recycleview etc. :

SampleApp >> app >> build.gradle

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0-alpha05'

    // app compact
    implementation "androidx.appcompat:appcompat:1.1.0-alpha05"

    // constraint layout
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

    // recycle view
    implementation 'androidx.recyclerview:recyclerview:1.1.0-alpha05'

    // glide
    implementation 'com.github.bumptech.glide:glide:4.9.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'

    // retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
    // gson convertor
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'

    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0-beta01'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-beta01'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

 

5.  Now Create a retrofit Client class in source file:

NetworkClient.kt

import java.util.concurrent.TimeUnit

import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object NetworkClient {

    private val BASE_URL = "https://reqres.in"
    private val TIMEOUT = 10
    var retrofit: Retrofit? = null
    /*
    This public static method will return Retrofit client
    anywhere in the appplication
    */
    val retrofitClient: Retrofit
        get() {
            if (retrofit == null) {
                val okHttpClientBuilder = OkHttpClient.Builder()
                okHttpClientBuilder.connectTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS)
                retrofit = Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .client(okHttpClientBuilder.build())
                        .build()
            }
            return retrofit!!
        }
}

 

6.  Create end point API : 

package datanapps.retrofitkotlin.services.users

import datanapps.retrofitkotlin.services.users.model.BaseUser
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.QueryMap
/**
 * API for getting User list from https://reqres.in/api/users?&page=1
 */
interface APIUser {
//https://reqres.in/api/users?page=1
    @GET("api/users?")
    fun getUserList(@QueryMap options: Map<String, String>): Call<BaseUser>
}

 

7. Create an Interface to listen Retrofit Event listener :

package datanapps.retrofitkotlin.services.network;

import retrofit2.Call;

public interface RetrofitEventListener {
     void onSuccess(Call call, Object response);
     void onError(Call call, Throwable t);
}

 

8. Create a implementation  class to call userAPI  With retrofit API :

 

package datanapps.retrofitkotlin.services.users

import java.util.HashMap
import datanapps.retrofitkotlin.services.network.NetworkClient
import datanapps.retrofitkotlin.services.network.RetrofitEventListener
import datanapps.retrofitkotlin.services.users.model.BaseUser
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response


class ApiUserRestClient {
    companion object {
        val instance = ApiUserRestClient()
    }

    private var mApiUser: APIUser? = null

    /**
     * Invoke getUserList via [Call] request.
     * @param retrofitEventListener of RetrofitEventListener.
     */

    //https://reqres.in/api/users?page=1

    fun getUserList(retrofitEventListener: RetrofitEventListener) {
        val retrofit = NetworkClient.retrofitClient
        mApiUser = retrofit.create<APIUser>(APIUser::class.java)

        val data = HashMap<String, String>()
        data["page"] = "1"

        val apiUserCall = mApiUser!!.getUserList(data)
        /*
        This is the line which actually sends a network request. Calling enqueue() executes a call asynchronously. It has two callback listeners which will invoked on the main thread
        */

        apiUserCall.enqueue(object : Callback<BaseUser> {

            override fun onResponse(call: Call<BaseUser>?, response: Response<BaseUser>?) {
                /*This is the success callback. Though the response type is JSON, with Retrofit we get the response in the form of WResponse POJO class
                 */
                if (response?.body() != null) {
                    retrofitEventListener.onSuccess(call, response?.body())
                }
            }
            override fun onFailure(call: Call<BaseUser>?, t: Throwable?) {
                /*
                Error callback
                */
                retrofitEventListener.onError(call, t)
            }
        })
    }
}

 

9. Create a model class this is base user class :

A. Generated all model class from  : http://www.jsonschema2pojo.org/ 

B. Paste your json response and generate Model.

C.  All model class generate in java you have to convert it into KOTLIN. 

D.   To convert Java class into KOTLIN :

Window >>   Ctrl + Shift +Alt+ K 

Mac >> Command + Shift +Alt+ K 

 

import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName

class BaseUser {

    @SerializedName("page")
    @Expose
    var page: Int? = null
    @SerializedName("per_page")
    @Expose
    var perPage: Int? = null
    @SerializedName("total")
    @Expose
    var total: Int? = null
    @SerializedName("total_pages")
    @Expose
    var totalPages: Int? = null
    @SerializedName("data")
    @Expose
    var data: List<User>? = null
}

 

10. This is User.kt  model class 

class User {

    @SerializedName("id")
    @Expose
    var id: Int? = null
    @SerializedName("email")
    @Expose
    var email: String? = null
    @SerializedName("first_name")
    @Expose
    var firstName: String? = null
    @SerializedName("last_name")
    @Expose
    var lastName: String? = null
    @SerializedName("avatar")
    @Expose
    var avatar: String? = null
}

 

11. Create a layout to display user  layout in adapter :   

layout_list_user.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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="wrap_content"
    android:layout_margin="8dp"
   >
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_alignParentStart="true"
        android:layout_centerInParent="true"
        android:padding="8dp"
        tools:ignore="MissingConstraints">

        <ImageView
            android:id="@+id/layout_list_user_icon"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:padding="1dp"
            android:contentDescription="@string/app_name"
            android:textColor="@color/black"
            />

        <TextView
            android:id="@+id/layout_list_user_day_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="1dp"
            android:text="sdsdsdsd"
            android:textStyle="bold"
            android:layout_marginStart="10dp"
            android:layout_toEndOf="@+id/layout_list_user_icon"
            android:textColor="@color/black"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/layout_list_user_email"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="1dp"
            android:text="sdsdsdsd"
            android:layout_marginStart="10dp"
            android:layout_toEndOf="@+id/layout_list_user_icon"
            android:layout_below="@+id/layout_list_user_day_name"
            android:textColor="@color/black"
            android:textSize="15sp" />
    </RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

 

12. Create adapter class to display user data :  

package datanapps.retrofitkotlin.view

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView

import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import datanapps.retrofitkotlin.R
import datanapps.retrofitkotlin.services.users.model.User


class UsersAdapter(private val context: Context, private val userList: List<User>) : RecyclerView.Adapter<UsersAdapter.UserViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        val itemView = LayoutInflater.from(parent.context)
                .inflate(R.layout.layout_list_user, parent, false)

        return UserViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        val user = userList[position]
        holder.userName.text = user.firstName +" "+ user.lastName
        holder.userEmail.text = user.email
          Glide.with(context)
                .load(user.avatar)
                .apply(RequestOptions().fitCenter())
                .into(holder.userIcon)

    }

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

    inner class UserViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        var userName: TextView
         var userEmail: TextView
         var userIcon: ImageView

        init {
            userName = view.findViewById(R.id.layout_list_user_day_name)
            userEmail = view.findViewById(R.id.layout_list_user_email)
            userIcon = view.findViewById(R.id.layout_list_user_icon)

        }
    }
}

 

13. Create a main layout xml 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".view.MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycle_view_book"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        app:layout_constraintTop_toBottomOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

14.  Create a main activity in this class we will hit Retrofit URL : 

package datanapps.retrofitkotlin.view

import androidx.appcompat.app.AppCompatActivity
import datanapps.retrofitkotlin.R

import android.os.Bundle
import android.util.Log
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import datanapps.retrofitkotlin.services.network.RetrofitEventListener
import datanapps.retrofitkotlin.services.users.ApiUserRestClient
import datanapps.retrofitkotlin.services.users.model.BaseUser
import datanapps.retrofitkotlin.services.users.model.User
import retrofit2.Call

class MainActivity : AppCompatActivity() {

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

    internal fun callUserListData() {

        ApiUserRestClient.instance.getUserList( object : RetrofitEventListener {
            override  fun onSuccess(call: Call<*>, response: Any) {
                if (response is BaseUser) {
                    Log.d("asd", "-----" + response.data!!.size)
                    setRecycleViewList(response.data!!);
                }
            }

            override fun onError(call: Call<*>, t: Throwable) {
                // snack bar that city can not find
            }
        })
    }

    private fun setRecycleViewList(userList: List<User>) {
        val recyclerView = findViewById<RecyclerView>(R.id.recycle_view_book)
        val mAdapter = UsersAdapter(this@MainActivity, userList)
        val mLayoutManager = LinearLayoutManager(applicationContext)
        recyclerView.layoutManager = mLayoutManager
        recyclerView.itemAnimator = DefaultItemAnimator()
        recyclerView.adapter = mAdapter
    }
}

 Hope it will help you.

Read More : https://square.github.io/retrofit/

Also, check out our Blogging for developers : 
Android Search View

Please download project and sample here.   RetrofitKotlin

If you enjoyed this story, please click LIKE button and SHARE to help others find it!

Please suggest ideas for my next blog in comment section.

Thank you so much, Have a great day !


Click Here To See More

What's Your Reaction?

like
6
dislike
2
love
1
funny
2
angry
4
sad
2
wow
9