Traditionally, you were using a listview to display several homogeneous elements in you Android app. However, this view is now deprecated. Android now offers an alternative, which aims to increase performance by only loading those elements, that are currently rendered on-screen: the RecyclerView.

This article shows you how to get started with the RecyclerView. To make things a bit more interesting, we will be using Kotlin instead of Java.

You can set up an Android project for Kotlin by simply clicking the checkbox for Kotlin support in the new project wizard.

Preceding Configuration

Before you can use the Recyclerview in your app, a little preparatory work is necessary. The first thing you’ll need to do is to add this dependency to your modules build.gradle file:

Basic GUI Setup

The next thing you’ll want to do is to set up a simple xaml page to display the view. I’ll be using a coordinator layout, which allows me to add a FloatingActionButton at a later stage.

The snippets I use in this article are from my ShoppingList-App, which is basically a minimalistic app to save shopping lists. The user can add and remove items from shopping lists, multiple shopping lists can be used at the same time.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<android.support.design.widget.CoordinatorLayout  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.jurtz.marcel.shoppinglist.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rvShoppingLists"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="8dp" />

</android.support.design.widget.CoordinatorLayout >```

## RecyclerView Components: Adapter & ViewHolder

While it offers the advantage of improved performance, the RecyclerView is a bit more complicated to create and requires additional components. In our _MainActivity_ class, the first thing to do now is to specify the RecyclerViews LayoutManager. This is required to define the appearance of the multiple items. I'd like to display them in a vertical list.

```kotlin rvShoppingLists.layoutManager = LinearLayoutManager(this)```

The next thing you'll want to do is to set the views adapter. You can think of the adapter as a bridge between view and model which defines the appearance of your the POJOs.

To implement the adapter, add a new class which inherits from _RecyclerView.Adapter<T>_. As you can see, this class is generic and requires a ViewHolder, I've also created a custom class for this purpose. The following snippet shows the methods that need to be overridden.

```kotlin class ShoppingListAdapter(var shoppingLists: List<ShoppingList?>) : RecyclerView.Adapter<ShoppingListViewHolder>() {

    override fun getItemCount(): Int {
        return 5
    }

    override fun onBindViewHolder(holder: ShoppingListViewHolder?, position: Int) {

    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ShoppingListViewHolder {
        
    }
}

class ShoppingListViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
   

}```

Note that I added _5_ as return value for _getItemCount()_, you can leave this for now, we will see what this does in the next steps.

## Custom Layout for RecyclerView Items

Now, we will add a new layout file (xml) to specify how each row in the RecyclerView should look like. For this purpose, I'd like to use a CardView with a nested LinearLayout that contains two TextViews. In my app, I'm using the first TextView to display a shopping lists description and the amount of items in the second one.

```xml <?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"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cvRowEntry"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardCornerRadius="4dp"
    android:layout_margin="8dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/lblShoppingListRowItemHeader"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:text="@string/rv_shopping_lists_placeholder_title"
            android:textSize="24sp" />

        <TextView
            android:id="@+id/lblShoppingListRowItemSubheader"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:text="@string/rv_shopping_lists_placeholder_subtitle" />
    </LinearLayout>
</android.support.v7.widget.CardView>```

Now we want to link the view to the RecyclerView in the adapter. To do this, we will update the onCreateViewHolder method we overrode earlier.

```kotlin override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ShoppingListViewHolder {
    val layoutInflater = LayoutInflater.from(parent?.context)
    val cellForRow = layoutInflater.inflate(R.layout.shopping_list_row, parent, false)
    return ShoppingListViewHolder(cellForRow)
}```

This tells the RecyclerView that each row should look like the layout we just created. If you have left the _5_ in the getItemCount()-method, you will see that the view is displayed 5 times when running the app.

## Adding real Data

Of course, that's not all we want. Currently, we can display multiple instances of the basic view, but we want to be able to show actual data. This is where the ViewHolder comes in. Usually, you will have access to a collection of objects that will be displayed in the RecyclerView.

In my snippet above, you can see that I already added a _List<ShoppingList?>_ parameter to the adapters constructor. The ShoppingList class basically just contains a description  and a List of ShoppingListItem-objects, that again only have a _description_ field.

The first thing to do now is to update the _getItemCount()_-method to actually return the amount of available objects:

```kotlin override fun getItemCount(): Int {
    return shoppingLists.size ?: 0
}```

In the next step, we will link the object to the view, which is done by the following:

```kotlin holder?.bindShoppingList(shoppingList = shoppingLists.get(position))```

And, last but not least, declaring the views properties to the objects variable values:

```kotlin class ShoppingListViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
    fun bindShoppingList(shoppingList: ShoppingList?) {
        view.lblShoppingListRowItemHeader.setText(shoppingList?.description)

        var suffix = ""
        var count = shoppingList?.items?.size ?: 0
        if(count == 1) {
            suffix = view.context.resources.getString(R.string.rv_shopping_list_items_suffix_single)
        } else {
            suffix = view.context.resources.getString(R.string.rv_shopping_list_items_suffix_multiple)
        }

        view.lblShoppingListRowItemSubheader.setText(count.toString() + " " + suffix)
    }
}```

That's it! I added the following code to my MainActivity to test the adapter:

```kotlin rvShoppingLists.layoutManager = LinearLayoutManager(this)

var list1 = ShoppingList()
list1.description = "Groceries"

var list2 = ShoppingList()
list2.description = "Clothes"

var list3 = ShoppingList()
list3.description = "Stuff for the apartment"

var list = listOf(list1, list2, list3)

rvShoppingLists.adapter = ShoppingListAdapter(list)```

&nbsp;