International Islamic University H-10, Islamabad, Pakistan
Mobile Applications Development
Week 12
Using RecyclerView and
Custom Adapter in Android
Engr. Rashid Farid Chishti
https://chishti.web.app
http://youtube.com/rfchishti
Introduction to RecyclerView
 A RecyclerView is a powerful and flexible view group in Android that is used to
display large sets of data in a scrollable list or grid.
 It’s an improved version of ListView and GridView, designed to be more
efficient and customizable.
 It is optimized for handling large lists of data with minimal memory usage by
reusing (recycling) item views.
 Advantages over ListView:
 Efficient view recycling with ViewHolder pattern (built-in).
 Supports vertical, horizontal, grid, and staggered layouts.
 Provides animations, decorations (dividers, spacing)
 Easy integration with custom adapters.
Introduction to RecyclerView
Vertical layout grid layout staggered layout
 Make sure you have the following in your build.gradle (app):
dependencies {
implementation
"androidx.recyclerview:recyclerview:1.3.2"
}
1. Adding RecyclerView Dependency
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/white"
android:id="@+id/main"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"/>
</LinearLayout>
1. Using RecyclerView (activity_main.xml)
package com.example.myfirstapp
import android.os.Bundle
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
1. Using RecyclerView (MainActivity.kt) (1/2)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -
>
val systemBars =
insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right,
systemBars.bottom)
insets
}
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
val data = listOf("Apple", "Banana", "Orange", "Mango", "Grapes")
recyclerView.adapter = Adapter_Fruits(data) { selectedItem ->
Toast.makeText(this, "Clicked: $selectedItem",
Toast.LENGTH_SHORT).show()
}
1. Using RecyclerView (MainActivity.kt) (2/2)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="5dp">
<TextView
android:id="@+id/tvItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:padding="5dp"
android:text="Fruit Name"
android:background="#FFFFC0" />
</LinearLayout>
1. Using RecyclerView (res/layout/item_fruit.xml)
package com.example.myfirstapp
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class Adapter_Fruits(
private val items: List<String>,
private val onItemClick: (String) -> Unit // callback function
) : RecyclerView.Adapter<Adapter_Fruits.ViewHolder_Fruits>() {
class ViewHolder_Fruits(itemView: View) :
RecyclerView.ViewHolder(itemView) {
val tvItem: TextView = itemView.findViewById(R.id.tvItem)
}
1. Using RecyclerView (Adapter_Fruits.kt) (1/2)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
ViewHolder_Fruits {
val view =
LayoutInflater.from(parent.context).inflate(R.layout.item_fruit,
parent,
false)
return ViewHolder_Fruits(view)
}
override fun onBindViewHolder(holder: ViewHolder_Fruits, position: Int) {
val item = items[position]
holder.tvItem.text = item
// Handle click event
holder.itemView.setOnClickListener {
onItemClick(item)
}
}
override fun getItemCount(): Int = items.size
1. Using RecyclerView (Adapter_Fruits.kt) (2/2)
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:width="2dp" android:color="#0000FF" />
<corners
android:bottomLeftRadius="10dp" android:bottomRightRadius="10dp"
android:topLeftRadius="10dp" android:topRightRadius="10dp"/>
<!-- <solid android:color="#92D050"> </solid> -->
<gradient android:angle="90"
android:type="linear" android:gradientRadius="200"
android:startColor="#92D050" android:endColor="#ffff00" />
<padding
android:top="1dp" android:bottom="1dp"
android:left="1dp" android:right="1dp" />
</shape>
2. Using RecyclerView (res/drawable/bg_round.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/bg_round"
android:padding="12dp" android:layout_marginBottom="5dp">
<ImageView
android:id="@+id/imgUser" android:layout_width="50dp"
android:layout_height="50dp" android:src="@mipmap/ic_launcher"
android:layout_marginEnd="12dp"/>
<TextView
android:id="@+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="User Name" android:textSize="18sp"
android:textStyle="bold"/>
</LinearLayout>
2. Using RecyclerView (res/layout/item_user.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/white"
android:id="@+id/main"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"/>
</LinearLayout>
2. Using RecyclerView (activity_main.xml)
package com.example.myfirstapp
data class User(val name: String, val imageResId: Int)
2. Using RecyclerView (User.kt)
package com.example.myfirstapp
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class Adapter_User(
private var userList: List<User>,
private val onItemClick: (User) -> Unit) :
RecyclerView.Adapter<Adapter_User.UserViewHolder>() {
// UserViewHolder: Holds item views
inner class UserViewHolder(itemView: View) :
RecyclerView.ViewHolder(itemView) {
val imgUser: ImageView = itemView.findViewById(R.id.imgUser)
val txtName: TextView = itemView.findViewById(R.id.txtName)
}
2. Using RecyclerView (Adapter_User.kt) (1/2)
override fun onCreateViewHolder(parent:ViewGroup, viewType:Int):
UserViewHolder {
val view =
LayoutInflater.from(parent.context).inflate(R.layout.item_user,
parent,
false)
return UserViewHolder(view)
}
override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
val user = userList[position]
holder.imgUser.setImageResource(user.imageResId)
holder.txtName.text = user.name
holder.itemView.setOnClickListener {
// Handle click
onItemClick(user)
}
}
override fun getItemCount(): Int = userList.size
2. Using RecyclerView (Adapter_User.kt) (2/2)
package com.example.myfirstapp
import android.os.Bundle
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var adapter: Adapter_User
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
2. Using RecyclerView (MainActivity.kt) (1/2)
2. Using RecyclerView (MainActivity.kt) (2/2)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -
>
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right,
systemBars.bottom)
insets
}
val users_list = listOf( // Sample Data
User("Alice", R.mipmap.ic_launcher), User("Bob",
R.mipmap.ic_launcher),
User("Charlie", R.mipmap.ic_launcher)
)
// Adapter setup with click listener
adapter = Adapter_User(users_list) { user ->
Toast.makeText(this, "Clicked: ${user.name}",
Toast.LENGTH_SHORT).show()
}
recyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)

Week 12 - Using RecyclerView and Custom Adapter in Android.pptx