📋 Screens, Lists और Navigation · Lesson 22
RecyclerView (Lists)
RecyclerView क्यों?
लगभग हर app list दिखाती है: chats, products, notes। 1,000 items के लिए हर item का एक view बनाएँ तो phone की memory खत्म। RecyclerView सिर्फ़ screen भरने लायक rows बनाता है और scroll करने पर उन्हें recycle करता है।
4 हिस्से
Step 1: Data class
Kotlin
// Subject.kt
data class Subject(val name: String, val teacher: String, val emoji: String, val chapters: Int)
val subjects = listOf(
Subject("Maths", "Mr. Gupta", "📐", 14),
Subject("Physics", "Ms. Khan", "🔭", 12),
Subject("Chemistry", "Mr. Rao", "⚗️", 10),
Subject("Biology", "Dr. Mehta", "🧬", 16),
Subject("English", "Ms. Thomas", "📖", 9),
Subject("Computer", "Mr. Singh", "💻", 11)
)Step 2: Row layout
XML – res/layout/item_subject_row.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- res/layout/item_subject_row.xml – ONE row -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="16dp">
<TextView
android:id="@+id/tvEmoji"
android:layout_width="48dp"
android:layout_height="48dp"
android:gravity="center"
android:textSize="26sp" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="17sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tvTeacher"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:id="@+id/tvChapters"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>Step 3: Adapter + ViewHolder
Kotlin – SubjectAdapter.kt
// SubjectAdapter.kt
class SubjectAdapter(private val items: List<Subject>) :
RecyclerView.Adapter<SubjectAdapter.SubjectViewHolder>() {
// ViewHolder = holds the views of ONE row (so we don't look them up again)
class SubjectViewHolder(val binding: ItemSubjectRowBinding) : RecyclerView.ViewHolder(binding.root)
// 1. called only a few times: create a new row view
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubjectViewHolder {
val binding = ItemSubjectRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return SubjectViewHolder(binding)
}
// 2. called many times: put the data of position X into a row
override fun onBindViewHolder(holder: SubjectViewHolder, position: Int) {
val s = items[position]
holder.binding.tvEmoji.text = s.emoji
holder.binding.tvName.text = s.name
holder.binding.tvTeacher.text = s.teacher
holder.binding.tvChapters.text = "${s.chapters} ch."
}
// 3. how many rows?
override fun getItemCount() = items.size
}Step 4: Screen में जोड़ें
XML
<!-- activity_main.xml -->
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_subject_row" />Kotlin – MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.recyclerView.layoutManager = LinearLayoutManager(this)
binding.recyclerView.adapter = SubjectAdapter(subjects)
binding.recyclerView.addItemDecoration(
DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
)
}
}Recycling कैसे काम करती है
List update करना
Kotlin
class SubjectAdapter(private val items: MutableList<Subject>) : RecyclerView.Adapter<...>() {
fun add(subject: Subject) {
items.add(0, subject)
notifyItemInserted(0) // animate just the new row
}
fun removeAt(position: Int) {
items.removeAt(position)
notifyItemRemoved(position)
}
}
// notifyDataSetChanged() redraws everything – avoid it; use ListAdapter + DiffUtil (next lesson)आम गलतियाँ
- LayoutManager नहीं → list बिना error के खाली रहती है।
- Row root की height
match_parent→ हर row पूरी screen भर देती है।wrap_contentuse करें। attachToRoot = trueसे inflate → crash "child already has a parent"। हमेशाfalseदें।- Click listener logic पुरानी position पर निर्भर →
holder.bindingAdapterPositionuse करें।
सारांश
- Data class + row XML + Adapter (create, bind, count) + LayoutManager।
- ViewHolder references रखता है; scroll करते समय views recycle होते हैं।
- notifyDataSetChanged की जगह notifyItemInserted/Removed (या ListAdapter) use करें।
✅ Practice
20 Indian states की list उनकी capital और emoji icon के साथ दिखाइए। एक FAB जोड़िए जो animation के साथ ऊपर नया state जोड़े।
अक्सर पूछे जाने वाले प्रश्न (FAQ)
ListView क्यों नहीं?
ListView पुराना और कम flexible है। RecyclerView ViewHolder pattern ज़रूरी करता है, grids, animations, item decorations और DiffUtil support करता है, और modern apps यही use करती हैं।
LayoutManager क्या करता है?
यह तय करता है rows कैसे लगें: LinearLayoutManager (vertical या horizontal list), GridLayoutManager (grid) या StaggeredGridLayoutManager (Pinterest-style)।
मेरा RecyclerView कुछ क्यों नहीं दिखा रहा?
आमतौर पर LayoutManager missing है, list खाली है, getItemCount 0 लौटाता है, या scroll view के अंदर wrap_content से RecyclerView की height 0 है।
