Recycler View using Kotlin and xml

Aayush Puranik
5 min readApr 12, 2020
  1. Simple Recycler View using Linear Layout Manager
  2. Recycler View with card based layout
  3. Horizontal Recycler view
  4. Recycler View using Grid Layout Manager

A recycler view is a flexible and more advanced version of ListView.

Recycler view uses several components to display data in a list format. The parent component is RecyclerView and it is implemented in activity or fragment. A recycler view is filled by views provided by LayoutManager (LinearLayoutManager or GridLayoutManager). A view is represented by view holder objects, data for each cell is set in view holder. We can access a view holder object in Adapter class. The adapter class creates view for cell and also binds view with data. The RecyclerView creates only as many view holders as are needed to display the on-screen portion of the dynamic content, plus a few extra. As the user scrolls through the list, the RecyclerView takes the off-screen views and rebinds them to the data which is scrolling onto the screen.

Recycler View is used to display a list of elements and user can scroll to view the list of items. Below are few ways we can implement recycler view. The implementation is for read-only data and the click listener is not implemented for cell click. If you want to check click listener implementation for cell click this link (https://medium.com/@aayushpuranik/recycler-view-using-kotlin-with-click-listener-46e7884eaf59).

  1. For creating a recycler view basically we need 3 things :
  • Data (a list of items),
  • View (RecyclerView and layout to display row data),
  • Adapter(extends RecyclerView.Adapter).

2. For creating a RecyclerView we will use :

  • RecyclerView (.xml in activity or fragment)
  • A layout file for cell (.xml)
  • Model class (.kt)
  • Adapter class (.kt)

We need to add dependency for recycler view in build.gradle(Module:App)

implementation 'androidx.recyclerview:recyclerview:1.0.0'

or

Simple Recycler View using Linear Layout Manager

Recycler View layout (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=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Cell View (cell_view.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"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<ImageView
android:id="@+id/iconIV"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="5dp"
android:background="@android:color/darker_gray"
app:layout_constraintEnd_toStartOf="@+id/titleTV"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/titleTV"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textStyle="bold"
android:text="Title"
app:layout_constraintBottom_toTopOf="@+id/subtitleTV"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/iconIV"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="spread" />

<TextView
android:id="@+id/subtitleTV"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="12sp"
android:textStyle="normal"
android:text="Subtitle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/titleTV"
app:layout_constraintTop_toBottomOf="@+id/titleTV" />
</androidx.constraintlayout.widget.ConstraintLayout>

Model class:

data class Model(
val icon: Int,
val title: String,
val subtitle: String
)

Adapter (Adapter.kt):

class Adapter(private val context: Context,
private val list: ArrayList<Model>) : RecyclerView.Adapter<Adapter.ViewHolder>() {

class ViewHolder(view: View): RecyclerView.ViewHolder(view) {
val iconIV: ImageView = view.findViewById(R.id.iconIV)
val titleTV: TextView = view.findViewById(R.id.titleTV)
val subtitleTV: TextView = view.findViewById(R.id.subtitleTV)
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.cell_view,parent, false)
return ViewHolder(view)
}

override fun getItemCount(): Int {
return list.count()
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val data = list[position]
holder.iconIV.setImageDrawable(ContextCompat.getDrawable(context, data.icon))
holder.titleTV.text = data.title
holder.subtitleTV.text = data.subtitle
}
}

MainActivity.kt

class MainActivity : AppCompatActivity() {

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

val recyclerView: RecyclerView = findViewById(R.id.recycler_view)

recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = Adapter(this, fetchList())
}

private fun fetchList(): ArrayList<Model> {
val list = arrayListOf<Model>()

for (i in 0..9) {
val model = Model(
R.drawable.ic_collections_black_24dp,
"Title : $i", "Subtitle : $i")
list.add(model)
}
return list
}
}

Output:

For better cell view separation we can use Item Decorator like DividerItemDecorator. For addign DividerItemDecorator add just add single in MainActivity after setting adapter to recyclerView

val recyclerView: RecyclerView = findViewById(R.id.recycler_view)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = Adapter(this, fetchList())
recyclerView.addItemDecoration(DividerItemDecoration(this,RecyclerView.VERTICAL))

Recycler View using card View

For adding card layout to recycler view just add card View to cell_view.xml and also add card View dependency in build.gradle

implementation 'androidx.cardview:cardview:1.0.0'

Cell View (cell_view.kt)

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.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_marginStart="10dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="5dp"
android:background="@android:color/white"
android:elevation="5dp"
app:contentPadding="5dp">

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white">

<ImageView
android:id="@+id/iconIV"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="5dp"
android:background="@android:color/darker_gray"
app:layout_constraintEnd_toStartOf="@+id/titleTV"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/titleTV"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Title"
android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/subtitleTV"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/iconIV"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="spread" />

<TextView
android:id="@+id/subtitleTV"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="Subtitle"
android:textSize="12sp"
android:textStyle="normal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/titleTV"
app:layout_constraintTop_toBottomOf="@+id/titleTV" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView

Horizontal Recycler View

For making horizontal recycler view just add make a small change in recyclerView.layoutManager and it will make recycler view horizontal. The part highlighted below need to be added while setting Layout Manager in recycler view

val recyclerView: RecyclerView = findViewById(R.id.recycler_view)
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
recyclerView.adapter = Adapter(this, fetchList())

Recycler View using Grid Layout Manager

For using Grid Layout Manager just add the following line in MainActivity. As you can see the line highlighted, until now we were using LinearLayoutManager but we just need to write GridLayoutManager and pass 2 values : first is context of activity or fragment and second is number of items in a cell in this example we are passing 2 that means it will display 2 columns in a single cell.

val recyclerView: RecyclerView = findViewById(R.id.recycler_view)
recyclerView.layoutManager = GridLayoutManager(this, 2)
recyclerView.adapter = Adapter(this, fetchList())

--

--