Output data in RecyclerView using Kotlin

This is second part of my tutorial Api Client using Retrofit, RXJava and Kotlin. In first part we connected with API and received list of articles, but we only logged out data in Logcat. In this part I’ll show you how to output article list in RecyclerView and make it look nice with CardView.

If you did’t read first part of this tutorial series please check it here:
Api Client using Retrofit, RXJava and Kotlin

Add Support

Lets first include support for RecyclerView and CardView in our project by adding two lines in your projects build.gradle file.

build.gradle(Module:app)
     // add cardview and recyclerview support
    implementation 'com.android.support:cardview-v7:26.1.0'
    implementation 'com.android.support:recyclerview-v7:26.1.0'

Add RecyclerView in our MainActivty

We will first add RecyclerView in our MainActivity. Open your activity_main.xml file to edit layout and include RecyclerView like this:

activity_main.xml
<?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"
    tools:context="com.example.samir.apiclientapp.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/articles_recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.constraint.ConstraintLayout>

Don’t forget to define id for your RecyclerView because we will need it later, I’ll just name it articles_recycler because it will contain list of articles.

Define layout for articles in RecyclerView

Now when we have our RecyclerView ready we need to define layout for our articles. RecyclerView will use this layout to display every of our articles. It will define how every of article items looks in our RecyclerView. For this tutorial it will be really simple layout containing CardView with two TextViews, first for article title and second one for article body. Lets create layout resource file and name it card_layout.xml or however you want it and add CardView and two TextViews like in my example:

card_layout.xml
<?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardCornerRadius="4dp"
        android:layout_margin="5dp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="16dp">

            <TextView
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="16dp"
                android:text="Title"
                android:textColor="@color/cardview_dark_background"
                android:gravity="center_vertical"
                android:textSize="20sp" />

            <TextView
                android:id="@+id/body"
                android:text="Content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentStart="true"
                android:layout_below="@+id/title" />

        </RelativeLayout>
</android.support.v7.widget.CardView>

Don’t forget to define id’s for your TextViews because we will need it later to access our views using kotlinx android extension.
After you finished in your preview it should look something like this:


It’s only my example ofx you can style it however you want.

RecyclerView Adapter

After we have our layouts ready it’s time to define our RecyclerView Adapter which will accept list of articles, on click listener, inflate and populate our layouts with some real articles. Go and create new Kotlin file and name it ArticleAdapter.

ArticleAdapter.kt
package com.example.samir.apiclientapp
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.card_layout.view.*

class ArticleAdapter(
        private val articleList: List<Article>,
        private val listener: (Article) -> Unit
    ): RecyclerView.Adapter<ArticleAdapter.ArticleHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ArticleHolder(
            LayoutInflater.from(parent.context).inflate(R.layout.card_layout, parent, false))

    override fun onBindViewHolder(holder: ArticleHolder, position: Int) = holder.bind(articleList[position], listener)

    override fun getItemCount() = articleList.size

    class ArticleHolder(articleView: View): RecyclerView.ViewHolder(articleView) {

        fun bind(article: Article, listener: (Article) -> Unit) = with(itemView) {
            title.text = article.title
            body.text = article.body
            setOnClickListener { listener(article) }
        }
    }
}

If you check ArticleHolder you can see that you can access view directly using kotlinx android extension, just use TextView id’s to bind it’s text property with article object property. This means there is no need to use findViewById() which was source of many bugs before. Kotlinx makes data binding piece of cake really and as result we get shorter and more expressive code.

Initialize RecyclerView in our MainActivity

Now that we have all ready it’s easy to initialize our RecyclerView from our MainActivity and display our articles in nice little cards. Add new function in MainActivity which will setupRecycler:

MainActivity.kt
     
fun setupRecycler(articleList: List<Article>) {

        articles_recycler.setHasFixedSize(true)
        val layoutManager = LinearLayoutManager(this)
        layoutManager.orientation = LinearLayoutManager.VERTICAL
        articles_recycler.layoutManager = layoutManager
        articles_recycler.adapter = ArticleAdapter(articleList){
            Log.v("Article", it.id.toString())
        }

}

In this function we set layout manager, it’s orientation, and add it to our RecyclerView. We will also set our ArticlesAdapter as RecyclerView adapter, pass it list of articles and onclick listener which will simply output id of clicked article in our LogCat to see it’s working.

Edit our showArticles function which we created in part 1 of this tutorial to get list of articles. Now we will output result, list of articles using our recycler view by calling function setupRecycler and passing it result.

MainActivity.kt
     
    /* get list of articles */
    private fun showArticles() {

        disposable = client.getArticles()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        { result -> setupRecycler(result) },
                        { error -> Log.e("ERROR", error.message) }
                        )

    }

Ok that’s all guys, start your app and check your new article cards.
Hope this tutorial helped someone out there trying to learn Kotlin and migrate from Java. For full app code please check github repository

https://github.com/SKaDiZZ/apiclient

Recommended reading:

Share with your friends