यह कोडलैब, Android Kotlin Fundamentals कोर्स का हिस्सा है. अगर कोडलैब को क्रम से पूरा किया जाता है, तो आपको इस कोर्स से सबसे ज़्यादा फ़ायदा मिलेगा. कोर्स के सभी कोडलैब, Android Kotlin Fundamentals कोडलैब के लैंडिंग पेज पर दिए गए हैं.
परिचय
इस कोडलैब में, आपको RecyclerView
में दिखने वाली सूची की पूरी चौड़ाई में हेडर जोड़ने का तरीका बताया गया है. आपको पिछले कोडलैब के स्लीप-ट्रैकर ऐप्लिकेशन का इस्तेमाल करना होगा.
आपको पहले से क्या पता होना चाहिए
- ऐक्टिविटी, फ़्रैगमेंट, और व्यू का इस्तेमाल करके, बुनियादी यूज़र इंटरफ़ेस बनाने का तरीका.
- एक फ़्रैगमेंट से दूसरे फ़्रैगमेंट पर जाने का तरीका और फ़्रैगमेंट के बीच डेटा ट्रांसफ़र करने के लिए,
safeArgs
का इस्तेमाल करने का तरीका. - मॉडल, मॉडल फ़ैक्ट्री, ट्रांसफ़ॉर्मेशन, और
LiveData
और उनके ऑब्ज़र्वर देखें. Room
डेटाबेस बनाने, DAO बनाने, और इकाइयों को तय करने का तरीका.- डेटाबेस इंटरैक्शन और लंबे समय तक चलने वाले अन्य टास्क के लिए, को-रूटीन का इस्तेमाल कैसे करें.
Adapter
,ViewHolder
, और आइटम लेआउट के साथ बुनियादीRecyclerView
को लागू करने का तरीका.RecyclerView
के लिए डेटा बाइंडिंग लागू करने का तरीका.- डेटा को बदलने के लिए, बाइंडिंग अडैप्टर बनाने और उनका इस्तेमाल करने का तरीका.
GridLayoutManager
का इस्तेमाल कैसे करें.RecyclerView.
में मौजूद आइटम पर क्लिक को कैप्चर और हैंडल करने का तरीका
आपको क्या सीखने को मिलेगा
- अलग लेआउट वाले आइटम जोड़ने के लिए,
RecyclerView
के साथ एक से ज़्यादाViewHolder
का इस्तेमाल करने का तरीका. खास तौर पर,RecyclerView
में दिखाए गए आइटम के ऊपर हेडर जोड़ने के लिए, दूसरेViewHolder
का इस्तेमाल कैसे करें.
आपको क्या करना होगा
- इस सीरीज़ के पिछले कोडलैब में दिए गए TrackMySleepQuality ऐप्लिकेशन का इस्तेमाल करें.
RecyclerView
में दिखाई गई नींद की रातों के ऊपर, स्क्रीन की पूरी चौड़ाई में एक हेडर जोड़ें.
नींद को ट्रैक करने वाले जिस ऐप्लिकेशन का इस्तेमाल किया जा रहा है उसमें तीन स्क्रीन होती हैं. इन्हें फ़्रैगमेंट के तौर पर दिखाया जाता है. इनके बारे में यहां दी गई इमेज में बताया गया है.
बाईं ओर दिखाई गई पहली स्क्रीन पर, ट्रैकिंग शुरू और बंद करने के बटन हैं. स्क्रीन पर, उपयोगकर्ता की नींद से जुड़ा कुछ डेटा दिखाया गया है. मिटाएं बटन दबाने पर, ऐप्लिकेशन ने उपयोगकर्ता के लिए जो भी डेटा इकट्ठा किया है वह हमेशा के लिए मिट जाता है. बीच में दिखाई गई दूसरी स्क्रीन, नींद की क्वालिटी की रेटिंग चुनने के लिए है. तीसरी स्क्रीन, ज़्यादा जानकारी वाला व्यू है. यह तब खुलता है, जब उपयोगकर्ता ग्रिड में मौजूद किसी आइटम पर टैप करता है.
यह ऐप्लिकेशन, यूज़र इंटरफ़ेस (यूआई) कंट्रोलर, व्यू मॉडल, और LiveData
के साथ-साथ Room
डेटाबेस का इस्तेमाल करता है. इससे नींद के डेटा को सेव किया जा सकता है.
इस कोडलैब में, दिखाए गए आइटम की ग्रिड में एक हेडर जोड़ा जाता है. आपकी मुख्य स्क्रीन कुछ ऐसी दिखेगी:
इस कोडलैब में, RecyclerView
में अलग-अलग लेआउट का इस्तेमाल करने वाले आइटम शामिल करने का सामान्य सिद्धांत बताया गया है. इसका एक सामान्य उदाहरण, आपकी सूची या ग्रिड में हेडर होना है. किसी सूची में, आइटम के कॉन्टेंट के बारे में बताने के लिए सिर्फ़ एक हेडर हो सकता है. किसी सूची में, आइटम को ग्रुप करने और अलग करने के लिए कई हेडर भी हो सकते हैं.
RecyclerView
को आपके डेटा या हर आइटम के लेआउट के बारे में कोई जानकारी नहीं होती. LayoutManager
स्क्रीन पर आइटम व्यवस्थित करता है. हालांकि, अडैप्टर, डेटा को दिखाने के लिए अडैप्ट करता है और व्यू होल्डर को RecyclerView
पर पास करता है. इसलिए, आपको अडैप्टर में हेडर बनाने के लिए कोड जोड़ना होगा.
हेडर जोड़ने के दो तरीके
RecyclerView
में, सूची के हर आइटम का इंडेक्स नंबर 0 से शुरू होता है. उदाहरण के लिए:
[Actual Data] -> [Adapter Views]
[0: SleepNight] -> [0: SleepNight]
[1: SleepNight] -> [1: SleepNight]
[2: SleepNight] -> [2: SleepNight]
किसी सूची में हेडर जोड़ने का एक तरीका यह है कि आप अपने अडैप्टर में बदलाव करें, ताकि वह किसी दूसरे ViewHolder
का इस्तेमाल कर सके. इसके लिए, उन इंडेक्स की जांच करें जहां आपको हेडर दिखाना है. Adapter
, हेडर को ट्रैक करने के लिए ज़िम्मेदार होगा. उदाहरण के लिए, टेबल में सबसे ऊपर हेडर दिखाने के लिए, आपको इंडेक्स किए गए आइटम को लेआउट करते समय, हेडर के लिए अलग ViewHolder
वैल्यू दिखानी होगी. इसके बाद, अन्य सभी आइटम को हेडर ऑफ़सेट के साथ मैप किया जाएगा. जैसा कि यहां दिखाया गया है.
[Actual Data] -> [Adapter Views]
[0: Header]
[0: SleepNight] -> [1: SleepNight]
[1: SleepNight] -> [2: SleepNight]
[2: SleepNight] -> [3: SleepNight.
हेडर जोड़ने का दूसरा तरीका यह है कि अपनी डेटा ग्रिड के लिए, बैकअप के तौर पर इस्तेमाल किए जा रहे डेटासेट में बदलाव करें. दिखाया जाने वाला सारा डेटा सूची में सेव होता है. इसलिए, हेडर दिखाने के लिए सूची में आइटम शामिल किए जा सकते हैं. इसे समझना थोड़ा आसान है. हालांकि, इसके लिए आपको यह सोचना होगा कि ऑब्जेक्ट कैसे डिज़ाइन किए जाएं, ताकि अलग-अलग आइटम टाइप को एक ही सूची में शामिल किया जा सके. इस तरीके से लागू करने पर, अडैप्टर को पास किए गए आइटम दिखेंगे. इसलिए, पोज़िशन 0 पर मौजूद आइटम हेडर है और पोज़िशन 1 पर मौजूद आइटम SleepNight
है. यह सीधे तौर पर स्क्रीन पर मौजूद कॉन्टेंट से मैप होता है.
[Actual Data] -> [Adapter Views]
[0: Header] -> [0: Header]
[1: SleepNight] -> [1: SleepNight]
[2: SleepNight] -> [2: SleepNight]
[3: SleepNight] -> [3: SleepNight]
हर तरीके के अपने फ़ायदे और नुकसान हैं. डेटासेट बदलने से, अडैप्टर कोड के बाकी हिस्से में ज़्यादा बदलाव नहीं होता. साथ ही, डेटा की सूची में बदलाव करके हेडर लॉजिक जोड़ा जा सकता है. दूसरी ओर, हेडर के इंडेक्स की जांच करके अलग ViewHolder
का इस्तेमाल करने से, हेडर के लेआउट को ज़्यादा आसानी से कंट्रोल किया जा सकता है. इससे अडैप्टर को यह तय करने में भी मदद मिलती है कि डेटा को व्यू के हिसाब से कैसे अडैप्ट किया जाए. इसके लिए, बैकअप डेटा में बदलाव करने की ज़रूरत नहीं होती.
इस कोडलैब में, आपको अपनी RecyclerView
को अपडेट करना है, ताकि सूची की शुरुआत में हेडर दिख सके. इस मामले में, आपका ऐप्लिकेशन हेडर के लिए अलग ViewHolder
और डेटा आइटम के लिए अलग ViewHolder
का इस्तेमाल करेगा. ऐप्लिकेशन, सूची के इंडेक्स की जांच करेगा. इससे यह तय किया जा सकेगा कि किस ViewHolder
का इस्तेमाल करना है.
पहला चरण: DataItem क्लास बनाना
आइटम के टाइप को अलग करने और अडैप्टर को सिर्फ़ "आइटम" से डील करने की अनुमति देने के लिए, एक डेटा होल्डर क्लास बनाई जा सकती है. यह क्लास, SleepNight
या Header
को दिखाती है. इसके बाद, आपका डेटासेट, डेटा होल्डर आइटम की सूची बन जाएगा.
GitHub से स्टार्टर ऐप्लिकेशन डाउनलोड किया जा सकता है. इसके अलावा, पिछले कोडलैब में बनाए गए SleepTracker ऐप्लिकेशन का इस्तेमाल जारी रखा जा सकता है.
- GitHub से RecyclerViewHeaders-Starter कोड डाउनलोड करें. RecyclerViewHeaders-Starter डायरेक्ट्री में, SleepTracker ऐप्लिकेशन का स्टार्टर वर्शन मौजूद है. यह कोडलैब के लिए ज़रूरी है. अगर आपको पसंद है, तो पिछले कोडलैब में बनाए गए ऐप्लिकेशन पर भी काम जारी रखा जा सकता है.
- SleepNightAdapter.kt खोलें.
SleepNightListener
क्लास के नीचे, सबसे ऊपर लेवल पर,sealed
क्लास कोDataItem
के तौर पर तय करें. यह क्लास, डेटा के किसी आइटम को दिखाती है.sealed
क्लास, क्लोज़्ड टाइप को तय करती है. इसका मतलब है किDataItem
की सभी सबक्लास को इस फ़ाइल में तय किया जाना चाहिए. इस वजह से, कंपाइलर को सबक्लास की संख्या के बारे में पता होता है. आपके कोड का कोई दूसरा हिस्सा,DataItem
का नया टाइप तय नहीं कर सकता. इससे आपका अडैप्टर काम करना बंद कर सकता है.
sealed class DataItem {
}
DataItem
क्लास के मुख्य हिस्से में, दो क्लास तय करें. ये क्लास, अलग-अलग तरह के डेटा आइटम को दिखाती हैं. पहलाSleepNightItem
है, जोSleepNight
के चारों ओर एक रैपर है. इसलिए, यहsleepNight
नाम की एक वैल्यू लेता है. इसे सील की गई क्लास का हिस्सा बनाने के लिए, इसे से बढ़ाएं.DataItem
data class SleepNightItem(val sleepNight: SleepNight): DataItem()
- दूसरी क्लास
Header
है, जिसका इस्तेमाल हेडर दिखाने के लिए किया जाता है. हेडर में कोई असल डेटा नहीं होता. इसलिए, इसेobject
के तौर पर तय किया जा सकता है. इसका मतलब है किHeader
का सिर्फ़ एक इंस्टेंस होगा. इसे फिर सेDataItem
करें.
object Header: DataItem()
- क्लास लेवल पर
DataItem
के अंदर,id
नाम कीabstract
Long
प्रॉपर्टी तय करें. जब अडैप्टर,DiffUtil
का इस्तेमाल करके यह तय करता है कि किसी आइटम में बदलाव हुआ है या नहीं और अगर हुआ है, तो किस तरह से, तबDiffUtil
को हर आइटम का आईडी पता होना चाहिए.DiffItemCallback
आपको एक गड़बड़ी दिखेगी, क्योंकिSleepNightItem
औरHeader
को ऐब्स्ट्रैक्ट प्रॉपर्टीid
को बदलना होगा.
abstract val id: Long
SleepNightItem
में,nightId
को वापस लाने के लिएid
को बदलें.
override val id = sleepNight.nightId
Header
में,id
को बदलें, ताकिLong.MIN_VALUE
वैल्यू मिले. यह बहुत छोटी संख्या होती है. इसका मतलब है कि -2 की घात 63. इसलिए, यह कभी भी किसी मौजूदाnightId
से मेल नहीं खाएगा.
override val id = Long.MIN_VALUE
- आपका पूरा किया गया कोड ऐसा दिखना चाहिए. साथ ही, आपका ऐप्लिकेशन बिना किसी गड़बड़ी के बनना चाहिए.
sealed class DataItem {
abstract val id: Long
data class SleepNightItem(val sleepNight: SleepNight): DataItem() {
override val id = sleepNight.nightId
}
object Header: DataItem() {
override val id = Long.MIN_VALUE
}
}
दूसरा चरण: हेडर के लिए ViewHolder बनाना
- header.xml नाम की नई लेआउट रिसॉर्स फ़ाइल में, हेडर के लिए लेआउट बनाएं. इसमें
TextView
दिखता है. इसमें कुछ भी दिलचस्प नहीं है, इसलिए यहां कोड दिया गया है.
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Sleep Results"
android:padding="8dp" />
"Sleep Results"
को स्ट्रिंग रिसॉर्स में बदलें और इसेheader_text
नाम दें.
<string name="header_text">Sleep Results</string>
- SleepNightAdapter.kt में,
SleepNightAdapter
के अंदर,ViewHolder
क्लास के ऊपर, एक नईTextViewHolder
क्लास बनाएं. यह क्लास, textview.xml लेआउट को बड़ा करती है औरTextViewHolder
इंस्टेंस दिखाती है. आपने यह काम पहले भी किया है. इसलिए, यहां कोड दिया गया है. आपकोView
औरR
इंपोर्ट करना होगा:
class TextViewHolder(view: View): RecyclerView.ViewHolder(view) {
companion object {
fun from(parent: ViewGroup): TextViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val view = layoutInflater.inflate(R.layout.header, parent, false)
return TextViewHolder(view)
}
}
}
तीसरा चरण: SleepNightAdapter को अपडेट करना
इसके बाद, आपको SleepNightAdapter
के बारे में एलान अपडेट करना होगा. इसे सिर्फ़ एक तरह के ViewHolder
का इस्तेमाल करने के बजाय, किसी भी तरह के व्यू होल्डर का इस्तेमाल करने की सुविधा देनी होगी.
आइटम के टाइप तय करना
SleepNightAdapter.kt
में, सबसे ऊपर के लेवल पर,import
स्टेटमेंट के नीचे औरSleepNightAdapter
के ऊपर, व्यू टाइप के लिए दो कॉन्स्टेंट तय करें.RecyclerView
को हर आइटम के व्यू टाइप में अंतर करना होगा, ताकि वह उसे सही व्यू होल्डर असाइन कर सके.
private val ITEM_VIEW_TYPE_HEADER = 0
private val ITEM_VIEW_TYPE_ITEM = 1
SleepNightAdapter
के अंदर,getItemViewType()
को बदलने के लिए एक फ़ंक्शन बनाएं. इससे मौजूदा आइटम के टाइप के आधार पर, सही हेडर या आइटम कॉन्स्टेंट दिखेगा.
override fun getItemViewType(position: Int): Int {
return when (getItem(position)) {
is DataItem.Header -> ITEM_VIEW_TYPE_HEADER
is DataItem.SleepNightItem -> ITEM_VIEW_TYPE_ITEM
}
}
SleepNightAdapter की परिभाषा अपडेट करें
SleepNightAdapter
की परिभाषा में,ListAdapter
के पहले आर्ग्युमेंट कोSleepNight
सेDataItem
पर अपडेट करें.SleepNightAdapter
की परिभाषा में,ListAdapter
के दूसरे सामान्य तर्क कोSleepNightAdapter.ViewHolder
से बदलकरRecyclerView.ViewHolder
करें. आपको ज़रूरी अपडेट के लिए कुछ गड़बड़ियां दिखेंगी. साथ ही, आपकी क्लास का हेडर इस तरह दिखना चाहिए.
class SleepNightAdapter(val clickListener: SleepNightListener):
ListAdapter<DataItem, RecyclerView.ViewHolder>(SleepNightDiffCallback()) {
onCreateViewHolder() अपडेट करना
onCreateViewHolder()
के हस्ताक्षर को बदलकरRecyclerView.ViewHolder
करें.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder
onCreateViewHolder()
तरीके को लागू करने की सुविधा को बड़ा करें, ताकि हर आइटम टाइप के लिए सही व्यू होल्डर की जांच की जा सके और उसे वापस किया जा सके. अपडेट किया गया आपका तरीका, नीचे दिए गए कोड की तरह दिखना चाहिए.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
ITEM_VIEW_TYPE_HEADER -> TextViewHolder.from(parent)
ITEM_VIEW_TYPE_ITEM -> ViewHolder.from(parent)
else -> throw ClassCastException("Unknown viewType ${viewType}")
}
}
onBindViewHolder() अपडेट करना
onBindViewHolder()
के पैरामीटर टाइप कोViewHolder
से बदलकरRecyclerView.ViewHolder
करें.
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int)
- सिर्फ़
ViewHolder
होने पर, व्यू होल्डर को डेटा असाइन करने के लिए कोई शर्त जोड़ें.
when (holder) {
is ViewHolder -> {...}
getItem()
से मिले ऑब्जेक्ट टाइप कोDataItem.SleepNightItem
में बदलता है. आपका पूरा किया गयाonBindViewHolder()
फ़ंक्शन ऐसा दिखना चाहिए.
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is ViewHolder -> {
val nightItem = getItem(position) as DataItem.SleepNightItem
holder.bind(nightItem.sleepNight, clickListener)
}
}
}
diffUtil कॉलबैक अपडेट करना
SleepNightDiffCallback
में दिए गए तरीकों को बदलकर,SleepNight
के बजाय अपनी नईDataItem
क्लास का इस्तेमाल करें. नीचे दिए गए कोड में दिखाए गए तरीके से, लिंट की चेतावनी को छिपाएं.
class SleepNightDiffCallback : DiffUtil.ItemCallback<DataItem>() {
override fun areItemsTheSame(oldItem: DataItem, newItem: DataItem): Boolean {
return oldItem.id == newItem.id
}
@SuppressLint("DiffUtilEquals")
override fun areContentsTheSame(oldItem: DataItem, newItem: DataItem): Boolean {
return oldItem == newItem
}
}
हेडर जोड़ना और सबमिट करना
SleepNightAdapter
के अंदर,onCreateViewHolder()
के नीचे,addHeaderAndSubmitList()
फ़ंक्शन को यहां दिखाए गए तरीके से तय करें. यह फ़ंक्शन,SleepNight
की सूची लेता है. अपनी सूची सबमिट करने के लिए,ListAdapter
की ओर से उपलब्ध कराए गएsubmitList()
का इस्तेमाल करने के बजाय, आपको इस फ़ंक्शन का इस्तेमाल करके हेडर जोड़ना होगा. इसके बाद, सूची सबमिट करनी होगी.
fun addHeaderAndSubmitList(list: List<SleepNight>?) {}
addHeaderAndSubmitList()
के अंदर, अगर पास की गई सूचीnull
है, तो सिर्फ़ हेडर दिखाएं. ऐसा न होने पर, हेडर को सूची के सबसे ऊपर जोड़ें. इसके बाद, सूची सबमिट करें.
val items = when (list) {
null -> listOf(DataItem.Header)
else -> listOf(DataItem.Header) + list.map { DataItem.SleepNightItem(it) }
}
submitList(items)
- SleepTrackerFragment.kt खोलें और
submitList()
कोaddHeaderAndSubmitList()
में बदलें.
- अपने ऐप्लिकेशन को चलाएं और देखें कि नींद से जुड़े आइटम की सूची में, आपका हेडर पहले आइटम के तौर पर कैसे दिखता है.
इस ऐप्लिकेशन के लिए, दो समस्याएं ठीक करनी होंगी. इनमें से एक समस्या दिख रही है और दूसरी नहीं दिख रही है.
- हेडर, सबसे ऊपर बाएं कोने में दिखता है और इसे आसानी से पहचाना नहीं जा सकता.
- एक हेडर वाली छोटी सूची के लिए, इससे ज़्यादा फ़र्क़ नहीं पड़ता. हालांकि, आपको यूज़र इंटरफ़ेस (यूआई) थ्रेड पर
addHeaderAndSubmitList()
में सूची में बदलाव नहीं करना चाहिए. मान लीजिए कि आपके पास सैकड़ों आइटम वाली कोई सूची है, जिसमें कई हेडर हैं. साथ ही, यह तय करने के लिए लॉजिक है कि आइटम कहां डालने हैं. यह काम एक को-रूटीन में होना चाहिए.
कोरूटीन का इस्तेमाल करने के लिए, addHeaderAndSubmitList()
को बदलें:
SleepNightAdapter
क्लास में सबसे ऊपर,Dispatchers.Default
की मदद सेCoroutineScope
को तय करें.
private val adapterScope = CoroutineScope(Dispatchers.Default)
addHeaderAndSubmitList()
में, सूची में बदलाव करने के लिएadapterScope
में एक कोरूटीन लॉन्च करें. इसके बाद, सूची सबमिट करने के लिएDispatchers.Main
कॉन्टेक्स्ट पर स्विच करें. इसे नीचे दिए गए कोड में दिखाया गया है.
fun addHeaderAndSubmitList(list: List<SleepNight>?) {
adapterScope.launch {
val items = when (list) {
null -> listOf(DataItem.Header)
else -> listOf(DataItem.Header) + list.map { DataItem.SleepNightItem(it) }
}
withContext(Dispatchers.Main) {
submitList(items)
}
}
}
- आपका कोड बिल्ड और रन होना चाहिए. साथ ही, आपको कोई अंतर नहीं दिखेगा.
फ़िलहाल, हेडर की चौड़ाई ग्रिड पर मौजूद अन्य आइटम की चौड़ाई के बराबर है. यह हॉरिज़ॉन्टल और वर्टिकल तौर पर एक स्पैन लेता है. पूरी ग्रिड में, एक स्पैन की चौड़ाई वाले तीन आइटम हॉरिज़ॉन्टल तौर पर फ़िट होते हैं. इसलिए, हेडर को हॉरिज़ॉन्टल तौर पर तीन स्पैन का इस्तेमाल करना चाहिए.
हेडर की चौड़ाई को ठीक करने के लिए, आपको GridLayoutManager
को यह बताना होगा कि डेटा को सभी कॉलम में कब फैलाना है. इसके लिए, GridLayoutManager
पर SpanSizeLookup
को कॉन्फ़िगर करें. यह एक कॉन्फ़िगरेशन ऑब्जेक्ट है. इसका इस्तेमाल GridLayoutManager
यह तय करने के लिए करता है कि सूची में मौजूद हर आइटम के लिए कितने स्पैन का इस्तेमाल किया जाए.
- SleepTrackerFragment.kt खोलें.
onCreateView()
के आखिर में,manager
को तय करने वाला कोड ढूंढें.
val manager = GridLayoutManager(activity, 3)
- नीचे दिए गए तरीके से,
manager
के नीचेmanager.spanSizeLookup
को तय करें. आपकोobject
बनाना होगा, क्योंकिsetSpanSizeLookup
में लैम्डा फ़ंक्शन का इस्तेमाल नहीं किया जा सकता. Kotlin मेंobject
बनाने के लिए,object : classname
टाइप करें. इस मामले में,GridLayoutManager.SpanSizeLookup
.
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
}
- कंस्ट्रक्टर को कॉल करने के लिए, आपको कंपाइलर से जुड़ी गड़बड़ी का मैसेज मिल सकता है. अगर ऐसा होता है, तो कंस्ट्रक्टर कॉल लागू करने के लिए,
Option+Enter
(Mac) याAlt+Enter
(Windows) का इस्तेमाल करके इंटेंशन मेन्यू खोलें.
- इसके बाद, आपको
object
पर गड़बड़ी का मैसेज मिलेगा. इसमें बताया जाएगा कि आपको तरीकों को बदलना होगा. कर्सर कोobject
पर रखें. इसके बाद, इंटेंशन मेन्यू खोलने के लिएOption+Enter
(Mac) याAlt+Enter
(Windows) दबाएं. फिर,getSpanSize()
तरीके को बदलें.
getSpanSize()
के मुख्य हिस्से में, हर पोज़िशन के लिए सही स्पैन साइज़ दिखाएं. पोजीशन 0 का स्पैन साइज़ 3 है और बाकी पोजीशन का स्पैन साइज़ 1 है. आपका पूरा कोड, यहां दिए गए कोड की तरह दिखना चाहिए:
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int) = when (position) {
0 -> 3
else -> 1
}
}
- हेडर को बेहतर बनाने के लिए, header.xml खोलें और इस कोड को लेआउट फ़ाइल header.xml में जोड़ें.
android:textColor="@color/white_text_color"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:background="@color/colorAccent"
- अपना ऐप्लिकेशन चलाएं. यह नीचे दिए गए स्क्रीनशॉट की तरह दिखना चाहिए.
बधाई हो! प्रक्रिया पूरी हो गई है.
Android Studio प्रोजेक्ट: RecyclerViewHeaders
- हेडर आम तौर पर ऐसा आइटम होता है जो सूची की पूरी चौड़ाई में दिखता है. यह टाइटल या सेपरेटर के तौर पर काम करता है. किसी सूची में, आइटम के कॉन्टेंट के बारे में बताने के लिए एक हेडर हो सकता है. इसके अलावा, आइटम को ग्रुप करने और उन्हें एक-दूसरे से अलग करने के लिए, कई हेडर भी हो सकते हैं.
RecyclerView
अलग-अलग तरह के आइटम दिखाने के लिए, एक से ज़्यादा व्यू होल्डर का इस्तेमाल कर सकता है. उदाहरण के लिए, हेडर और सूची के आइटम.- हेडर जोड़ने का एक तरीका यह है कि अपने अडैप्टर में बदलाव करके, किसी दूसरे
ViewHolder
का इस्तेमाल किया जाए. इसके लिए, उन इंडेक्स की जांच करें जहां आपको हेडर दिखाना है.Adapter
, हेडर को ट्रैक करने के लिए ज़िम्मेदार होता है. - हेडर जोड़ने का दूसरा तरीका यह है कि अपनी डेटा ग्रिड के लिए, डेटासेट (सूची) में बदलाव करें. आपने इस कोडलैब में ऐसा ही किया है.
हेडर जोड़ने के लिए, यह तरीका अपनाएं:
- अपनी सूची में मौजूद डेटा को छोटा करने के लिए,
DataItem
बनाएं. इसमें हेडर या डेटा शामिल किया जा सकता है. - अडैप्टर में हेडर के लिए लेआउट वाला व्यू होल्डर बनाएं.
- किसी भी तरह के
RecyclerView.ViewHolder
का इस्तेमाल करने के लिए, अडैप्टर और उसके तरीकों को अपडेट करें. onCreateViewHolder()
में, डेटा आइटम के लिए सही टाइप का व्यू होल्डर दिखाएं.DataItem
क्लास के साथ काम करने के लिए,SleepNightDiffCallback
को अपडेट करें.- एक
addHeaderAndSubmitList()
फ़ंक्शन बनाएं, जो डेटासेट में हेडर जोड़ने के लिए कोरूटीन का इस्तेमाल करता हो. इसके बाद,submitList()
को कॉल करता हो. - सिर्फ़ हेडर को तीन स्पैन की चौड़ाई देने के लिए,
GridLayoutManager.SpanSizeLookup()
लागू करें.
Udacity का कोर्स:
Android डेवलपर का दस्तावेज़:
इस सेक्शन में, उन छात्र-छात्राओं के लिए होमवर्क असाइनमेंट की सूची दी गई है जो किसी शिक्षक के कोर्स के हिस्से के तौर पर इस कोडलैब पर काम कर रहे हैं. शिक्षक के पास ये विकल्प होते हैं:
- अगर ज़रूरी हो, तो होमवर्क असाइन करें.
- छात्र-छात्राओं को बताएं कि होमवर्क असाइनमेंट कैसे सबमिट किए जाते हैं.
- होमवर्क असाइनमेंट को ग्रेड दें.
शिक्षक इन सुझावों का इस्तेमाल अपनी ज़रूरत के हिसाब से कर सकते हैं. साथ ही, वे चाहें, तो कोई दूसरा होमवर्क भी दे सकते हैं.
अगर आपको यह कोडलैब खुद से पूरा करना है, तो अपनी जानकारी की जांच करने के लिए, इन होमवर्क असाइनमेंट का इस्तेमाल करें.
इन सवालों के जवाब दें
पहला सवाल
ViewHolder
के बारे में इनमें से कौनसी बात सही है?
▢ अडैप्टर, हेडर और अलग-अलग तरह के डेटा को सेव करने के लिए, कई ViewHolder
क्लास का इस्तेमाल कर सकता है.
▢ डेटा के लिए सिर्फ़ एक व्यू होल्डर और हेडर के लिए सिर्फ़ एक व्यू होल्डर हो सकता है.
▢ RecyclerView
में कई तरह के हेडर इस्तेमाल किए जा सकते हैं, लेकिन डेटा एक जैसा होना चाहिए.
▢ हेडर जोड़ते समय, सही जगह पर हेडर डालने के लिए RecyclerView
का इस्तेमाल किया जाता है.
दूसरा सवाल
आपको RecyclerView
के साथ कोरूटीन का इस्तेमाल कब करना चाहिए? सभी सही जवाब चुनें.
▢ कभी नहीं. RecyclerView
एक यूज़र इंटरफ़ेस (यूआई) एलिमेंट है और इसमें को-रूटीन का इस्तेमाल नहीं किया जाना चाहिए.
▢ लंबे समय तक चलने वाले ऐसे टास्क के लिए कोरूटीन का इस्तेमाल करें जिनसे यूज़र इंटरफ़ेस (यूआई) धीमा हो सकता है.
▢ सूची में बदलाव करने में ज़्यादा समय लग सकता है. इसलिए, आपको हमेशा कोरूटीन का इस्तेमाल करके बदलाव करने चाहिए.
▢ मुख्य थ्रेड को ब्लॉक होने से बचाने के लिए, निलंबन फ़ंक्शन के साथ कोरूटीन का इस्तेमाल करें.
तीसरा सवाल
एक से ज़्यादा ViewHolder
का इस्तेमाल करते समय, इनमें से कौनसा काम नहीं करना पड़ता?
▢ ViewHolder
में, ज़रूरत के मुताबिक लेआउट फ़ाइलें उपलब्ध कराएं.
▢ onCreateViewHolder()
में, डेटा आइटम के लिए सही टाइप का व्यू होल्डर दिखाएं.
▢ onBindViewHolder()
में, डेटा को सिर्फ़ तब बाइंड करें, जब व्यू होल्डर, डेटा आइटम के लिए सही टाइप का व्यू होल्डर हो.
▢ किसी भी RecyclerView.ViewHolder
को स्वीकार करने के लिए, अडैप्टर क्लास के सिग्नेचर को सामान्य बनाएं.
अगला सबक शुरू करें:
इस कोर्स में मौजूद अन्य कोडलैब के लिंक के लिए, Android Kotlin Fundamentals कोडलैब का लैंडिंग पेज देखें.