Getting Started With RecyclerView in Android — Kotlin

Jaz Allibhai
AndroidPub
Published in
5 min readJan 30, 2018

--

RecyclerView is used to load views to the activity when you don’t know how many views we need, or have a large number of individual item views to display in one activity. It saves memory by reusing views when you scroll in an activity instead of creating them all at the beginning when the activity first loads.

Loading all views at the beginning wastes memory since there will be many views loaded that cannot be seen on the screen. When developing an app, you always want to be aware of the memory cost of the features in your app. Android devices have limited memory, and your app will not be the only one running on a user’s device.

RecyclerView has three main parts: the layout, ViewHolder, and adapter.

The layout is the view that will be created for each item to be loaded into the RecyclerView.

A ViewHolder is used to cache the view objects in order to save memory.

The adapter creates new items in the form of ViewHolders, populates the ViewHolders with data, and returns information about the data.

For this RecyclerView example, I’ll be loading a list of animals into a RecyclerView.

Start a new project in Android Studio with an Empty Activity.

In activity_main.xml (design tab)

Delete the default TextView.

Search for RecyclerView in the view search box.

Drag the RecyclerView underneath the ConstraintLayout.

You will be asked to add recyclerview-v7 project dependency; select OK (if the dialogue box does not pop up, add the below line to the build.gradle(Module: app) file.

implementation ‘com.android.support:recyclerview-v7:26.1.0’

(switch out 26.1.0 for whatever appcompat version you’re running).

Also, make sure you’ve applied the kotlin-android-extensions plugin to the build.gradle file if it is not already there.

Give the RecyclerView an id of “rv_animal_list”.

build.gradle(module: app)

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 26
defaultConfig {
applicationId "com.example.android.rvtutorial"
minSdkVersion 17
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation 'com.android.support:recyclerview-v7:26.1.0'
}

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.android.rvtutorial.MainActivity"
>

<android.support.v7.widget.RecyclerView

android:id="@+id/rv_animal_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

</android.support.constraint.ConstraintLayout>

We need to build out each row to populate in the RecyclerView. For this, we need to create a new layout file. Create a new layout file called “animal_list_item”.

In animal_list_item.xml

Add a TextView and change the layout_height of the LinearLayout to “wrap_content” so it doesn’t only show one TextView per page.

Give the TextView an id of tv_animal_type.

animal_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<TextView
android:id="@+id/tv_animal_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:padding="20dp"
/>

</LinearLayout>

In MainActivity.kt

Create an ArrayList and add a bunch of animals to the list.

Add a LinearLayoutManager. Layout Managers are used to position views inside the RecyclerView. They also determine when to reuse item views that are no longer visible to the user.

(You can use GridLayoutManager instead of LinearLayoutManager if you want a grid layout and add the number of columns as a parameter)

We will then need to access the RecyclerView adapter and load our data into it. Call the adapter “AnimalAdapter”. Animal Adapter will take two parameters: the ArrayList of animals and context (this).

We will create the actual AnimalAdapter in the next step (you will get an error until the adapter is created).

MainActivity.kt

package com.example.android.rvtutorial

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

// Initializing an empty ArrayList to be filled with animals
val animals: ArrayList<String> = ArrayList()

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

// Loads animals into the ArrayList
addAnimals()

// Creates a vertical Layout Manager
rv_animal_list.layoutManager = LinearLayoutManager(this)

// You can use GridLayoutManager if you want multiple columns. Enter the number of columns as a parameter.
// rv_animal_list.layoutManager = GridLayoutManager(this, 2)

// Access the RecyclerView Adapter and load the data into it
rv_animal_list.adapter = AnimalAdapter(animals, this)

}

// Adds animals to the empty animals ArrayList
fun addAnimals() {
animals.add("dog")
animals.add("cat")
animals.add("owl")
animals.add("cheetah")
animals.add("raccoon")
animals.add("bird")
animals.add("snake")
animals.add("lizard")
animals.add("hamster")
animals.add("bear")
animals.add("lion")
animals.add("tiger")
animals.add("horse")
animals.add("frog")
animals.add("fish")
animals.add("shark")
animals.add("turtle")
animals.add("elephant")
animals.add("cow")
animals.add("beaver")
animals.add("bison")
animals.add("porcupine")
animals.add("rat")
animals.add("mouse")
animals.add("goose")
animals.add("deer")
animals.add("fox")
animals.add("moose")
animals.add("buffalo")
animals.add("monkey")
animals.add("penguin")
animals.add("parrot")
}
}

Create a new kotlin file in the same folder with MainActivity called “AnimalAdapter”

In AnimalAdapter.kt

Create an AnimalAdapter class that implements a RecyclerView Adapter. It will take two parameters: the ArrayList of animals and context (you will get an error — I’ll address that in a minute).

Create a ViewHolder class below the AnimalAdapter class. In the ViewHolder class, create a variable to hold the TextView (tv_animal_type) that we will be loading each animal into.

To get rid of the error in the AnimalAdapter class, override all three functions in the class (getItemCount, onCreateViewHolder, onBindViewHolder)

In getItemCount, we will return the number of animals in the list.

In onCreateViewHolder, we will inflate the animal_list_item view that we will be using to hold each list item.

In onBindViewHolder, we will bind the list items to TextViews.

AnimalAdapter.kt

package com.example.android.rvtutorial

import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.animal_list_item.view.*

class AnimalAdapter(val items : ArrayList<String>, val context: Context) : RecyclerView.Adapter<ViewHolder>() {

// Gets the number of animals in the list
override fun getItemCount(): Int {
return items.size
}

// Inflates the item views
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(context).inflate(R.layout.animal_list_item, parent, false))
}

// Binds each animal in the ArrayList to a view
override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
holder?.tvAnimalType?.text = items.get(position)
}
}

class ViewHolder (view: View) : RecyclerView.ViewHolder(view) {
// Holds the TextView that will add each animal to
val tvAnimalType = view.tv_animal_type
}

That’s it! Now run the project!

The full source code is available here.

Thanks for reading! Too keep up to date with my journey as an Android developer, follow me on Twitter.

--

--