How to use retrofit in kotlin

Right now in the world of development andorid is warmly discussing about the kotlin. If you follow the trend of android programming tutorial mostly on discussing kotlin. Well here, I will also participate to discuss about kotlin, and in this tutorial we will discuss how to use retrofit on kotlin.

SCENARIO

On this tutorial we will create an application that will display a list of quote  from rss feed json from my friend’s website kutip.org. The app wil look like this image bellow.

Getting Started

Please create a new project, on this tutorial I will give the name of his project retrofit kotlin or up to you will give name for this project. When finished creating the project it’s time to add dependencies for us using this retrofit. Well in this tutorial we will also use rxjava2 for implementing reactive programming. Nowadays people make apps will definitely not be left behind by using reactive programming. So let put it into our build gradle file.

// retrofit
implementation "com.squareup.retrofit2:retrofit:2.3.0"
implementation "com.squareup.retrofit2:adapter-rxjava2:2.3.0"
implementation "com.squareup.retrofit2:converter-gson:2.3.0"
// rxandroid
implementation "io.reactivex.rxjava2:rxandroid:2.0.1"

Network

It’s finished adding dependencies now for us to create classes to handle connections or retrieve APIs.

interface KutipApiService {
    @GET("id/feed.json")
    fun getQuote(): Flowable<Quote>
    companion object Factory {
        fun create(): KutipApiService {
            val retrofit = Retrofit.Builder()
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .baseUrl("https://kutip.org/")
                    .build()
            return retrofit.create(KutipApiService::class.java)
        }
    }
}

Class above will take care of all matters relating to API call which we will receive as flowable.

MODEL

Now we need a model of the data we will receive from the API which if in java we call it as POJO (Plain Old Java Object), which is a class with setter and getter. Well if in the kotlin we are familiar with the data class which is will make a POJO object in a way that is easier and shorter.

data class Quote(
        var items: List<Item> = listOf()
)
data class Item(
        var title: String = "",
        var author: String = "",
        var content_text: String = "",
        var url: String = ""
)

ADAPTER

Because we will display the data into the recyclerview then we need to create an adapter to handle the data that we will display in recyclerview.

class QuoteAdapter : RecyclerView.Adapter<QuoteHolder>() {
    private var data = mutableListOf<Item>()
    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): QuoteHolder {
        return QuoteHolder(
                LayoutInflater.from(parent?.context)
                        .inflate(R.layout.item_quote, parent, false)
        )
    }
    override fun onBindViewHolder(holder: QuoteHolder?, position: Int) {
        holder?.bindData(data[position])
    }
    override fun getItemCount(): Int = data.size
    fun addData(quotes: List<Item>?) {
        if (quotes != null)
            data.addAll(quotes)
        notifyDataSetChanged()
    }
}

And lastly do not forget to display data to view through viewholder that we have created.

class QuoteHolder(view: View) : RecyclerView.ViewHolder(view) {
    private val title = view.findViewById<TextView>(R.id.title)
    private val author = view.findViewById<TextView>(R.id.author)
    private val content = view.findViewById<TextView>(R.id.content)
    fun bindData(item: Item) {
        title.text = item.title
        author.text = "-- ${item.author} --"
        content.text = item.content_text
    }
}

And do not forget to view the item holder like this:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:clickable="true"
    android:focusable="true"
    android:foreground="?attr/selectableItemBackground"
    app:contentPadding="10dp">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="18sp" />
        <TextView
            android:id="@+id/content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/title"
            android:layout_marginTop="10dp"
            android:textColor="@color/black"
            android:textSize="18sp"
            android:textStyle="bold" />
        <TextView
            android:id="@+id/author"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_below="@id/content"
            android:layout_marginTop="10dp"
            android:textSize="16sp"
            android:textStyle="italic" />
    </RelativeLayout>
</android.support.v7.widget.CardView>

EXECUTE

It’s all done now we need scenarios to show loading as well as error messages while fetching data to the API. First we need to create his view first like this.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.ahmadrosid.retrofitkotlin.MainActivity"
    tools:showIn="@layout/activity_main">
    <ProgressBar
        android:id="@+id/loader"
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <android.support.v7.widget.RecyclerView
        android:id="@+id/listQuote"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>

And the execution looks like this:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)
        supportActionBar?.title = "Kutip.org"
        val apiService = KutipApiService.create()
        apiService.getQuote()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe { loader.show() }
                .doOnComplete { loader.hide() }
                .doOnError { loader.hide() }
                .map { it.items }
                .subscribe(
                        { displayQuote(it) },
                        { displayError(it) }
                )
    }
    private fun displayQuote(quotes: List<Item>?){
        val adapter = QuoteAdapter()
        adapter.addData(quotes)
        listQuote.apply {
            this.adapter = adapter
            layoutManager = LinearLayoutManager(applicationContext)
        }
    }
    private fun displayError(throwable: Throwable?) {
        Snackbar.make(listQuote, "Failed to display list quote. \n ${throwable?.localizedMessage}", Snackbar.LENGTH_LONG).show()
    }
    private fun View.show() {
        this.visibility = VISIBLE
    }
    private fun View.hide() {
        this.visibility = GONE
    }
}

Yups up here is done. How easy isn’t it?

For the source code of this tutorial example can be accessed here.

And if you want to kutip.org android version can also be downloaded in play store already available.

Leave a Reply

Your email address will not be published. Required fields are marked *