Android Kotlin से जुड़े बुनियादी बातें 07.5: RecyclerView में हेडर

यह कोडलैब Android Kotlin के बुनियादी कोर्स में शामिल है. अगर आप कोडलैब के क्रम में काम करते हैं, तो आपको इस कोर्स का ज़्यादा से ज़्यादा फ़ायदा मिलेगा. सभी कोर्स कोडलैब Android Kotlin से जुड़े बेसिक कोडलैब के लैंडिंग पेज पर दिए गए हैं.

परिचय

इस कोडलैब में, आप एक हेडर जोड़ने का तरीका जानेंगे, जो RecyclerView में दिखाई गई सूची की चौड़ाई का होता है. आपने पिछले कोडलैब से नींद के पैटर्न पर नज़र रखने वाले ऐप्लिकेशन बनाए हैं.

आपको क्या पता होना चाहिए

  • किसी ऐक्टिविटी, फ़्रैगमेंट, और व्यू का इस्तेमाल करके बेसिक यूज़र इंटरफ़ेस बनाने का तरीका.
  • फ़्रैगमेंट के बीच नेविगेट करने का तरीका और फ़्रैगमेंट के बीच डेटा पास करने के लिए, safeArgs का इस्तेमाल करने का तरीका जानें.
  • मॉडल, मॉडल फ़ैक्ट्री, बदलाव, और उनके LiveData की निगरानी करें.
  • Room डेटाबेस बनाने, डीएओ बनाने, और इकाइयों की जानकारी देने का तरीका.
  • डेटाबेस इंटरैक्शन और लंबे समय तक चलने वाले अन्य कामों के लिए कोरूटीन का इस्तेमाल कैसे करें.
  • Adapter, ViewHolder, और आइटम लेआउट के साथ बेसिक RecyclerView को लागू करने का तरीका.
  • RecyclerView के लिए, डेटा बाइंडिंग लागू करने का तरीका.
  • डेटा बदलने के लिए बाइंडिंग अडैप्टर बनाने और इस्तेमाल करने का तरीका.
  • GridLayoutManager इस्तेमाल करने का तरीका.
  • RecyclerView. में आइटम पर मिलने वाले क्लिक को कैसे कैप्चर और मैनेज करें

आप इन चीज़ों के बारे में जानेंगे

  • किसी दूसरे लेआउट के साथ आइटम जोड़ने के लिए, RecyclerView में एक से ज़्यादा ViewHolder इस्तेमाल करने का तरीका. खास तौर पर, RecyclerView में दिखाए गए आइटम के ऊपर दूसरा हेडर जोड़ने के लिए, दूसरे ViewHolder का इस्तेमाल कैसे करें.

आप क्या कर पाएंगे!

  • इस सीरीज़ के पिछले कोडलैब से, ShowMySleepquality ऐप्लिकेशन पर बनाएं.
  • RecyclerView में दिखाई गई नींद से जुड़ी रातों के ऊपर, स्क्रीन की चौड़ाई वाला हेडर जोड़ें.

आप जिस स्लीप-ट्रैकर ऐप्लिकेशन से शुरुआत करते हैं उसमें तीन स्क्रीन हैं. उन्हें फ़्रैगमेंट से दिखाया गया है, जैसा कि नीचे दी गई इमेज में दिखाया गया है.

बाईं ओर दिखाई गई पहली स्क्रीन पर, ट्रैकिंग शुरू और बंद करने के लिए बटन दिए गए हैं. स्क्रीन पर उपयोगकर्ता के सोने के कुछ डेटा की जानकारी दिखती है. हटाएं बटन, उपयोगकर्ता के लिए ऐप्लिकेशन के ज़रिए इकट्ठा किया गया सारा डेटा हमेशा के लिए मिटा देता है. दूसरी स्क्रीन के बीच में 'नींद की क्वालिटी' रेटिंग दिख रही है. तीसरी स्क्रीन, जानकारी वाला व्यू है. जब उपयोगकर्ता ग्रिड में किसी आइटम पर टैप करता है, तो यह स्क्रीन खुलती है.

यह ऐप्लिकेशन, यूज़र इंटरफ़ेस (यूआई) कंट्रोलर, व्यू मॉडल, और LiveData के साथ आसान आर्किटेक्चर का इस्तेमाल करता है. इससे Room की नींद से जुड़े डेटा का इस्तेमाल जारी रहता है.

इस कोडलैब (कोड बनाना सीखना) में, आप दिखाए गए आइटम की ग्रिड में एक हेडर जोड़ते हैं. आपकी फ़ाइनल मुख्य स्क्रीन इस तरह दिखेगी:

यह कोडलैब RecyclerView में अलग-अलग लेआउट का इस्तेमाल करने वाले आइटम को शामिल करने का सामान्य सिद्धांत सिखाता है. इसका एक सामान्य उदाहरण है अपनी सूची या ग्रिड में हेडर जोड़ना. आइटम के कॉन्टेंट के बारे में बताने के लिए, सूची में एक हेडर हो सकता है. एक सूची में एक ही सूची में, आइटम को ग्रुप करने और अलग करने के लिए एक से ज़्यादा हेडर हो सकते हैं.

RecyclerView को आपके डेटा के बारे में या हर आइटम के लेआउट से जुड़ी जानकारी नहीं होती. LayoutManager स्क्रीन पर आइटम को व्यवस्थित करता है, लेकिन अडैप्टर दिखाए जाने वाले डेटा को ज़रूरत के हिसाब से सेट करता है और व्यू होल्डर को RecyclerView के पास भेज देता है. इसलिए, अडैप्टर में हेडर बनाने के लिए आपको कोड जोड़ना होगा.

हेडर जोड़ने के दो तरीके

RecyclerView में, सूची का हर आइटम, 0 से शुरू होने वाले इंडेक्स नंबर से मेल खाता है. उदाहरण के लिए:

[असल डेटा] -> [अडैप्टर व्यू]

[0: SleepNight] -> [0: SleepNight]

[1: SleepNight] -> [1: SleepNight]

[2: SleepNight] -> [2: SleepNight]

सूची में हेडर जोड़ने का एक तरीका यह है कि आप इंडेक्स में बदलाव करके, अपने अडैप्टर में किसी दूसरे ViewHolder का इस्तेमाल करें. इसके लिए, आपको उन इंडेक्स को देखना होगा जिनमें हेडर को दिखाना है. हेडर का ट्रैक रखने की ज़िम्मेदारी Adapter की होगी. उदाहरण के लिए, टेबल के सबसे ऊपर कोई हेडर दिखाने के लिए, आपको शून्य से इंडेक्स किए गए आइटम को रखते हुए हेडर के लिए एक अलग ViewHolder दिखाना होगा. इसके बाद, बाकी सभी आइटम को हेडर ऑफ़सेट के साथ मैप किया जाएगा, जैसा कि नीचे दिखाया गया है.

[असल डेटा] -> [अडैप्टर व्यू]

[0: हेडर]

[0: SleepNight] -> [1: SleepNight]

[1: SleepNight] -> [2: SleepNight]

[2: SleepNight] -> [3: SleepNight.

हेडर जोड़ने का एक और तरीका, अपने डेटा ग्रिड के बैकिंग डेटासेट में बदलाव करना है. चूंकि दिखाया जाने वाला सभी डेटा एक सूची में संग्रहित किया जाता है, इसलिए हेडर दिखाने के लिए सूची में आइटम शामिल करने के लिए आप उसमें बदलाव कर सकते हैं. यह समझना थोड़ा आसान है, लेकिन आपको यह सोचना होगा कि आप अपने ऑब्जेक्ट को कैसे डिज़ाइन करते हैं. इससे आप अलग-अलग तरह के आइटम को मिलाकर एक सूची बना सकते हैं. इस तरह लागू किया गया, अडैप्टर पास किए गए आइटम दिखाएगा. इसलिए, क्रम संख्या 0 पर मौजूद आइटम एक हेडर है और क्रम संख्या 1 पर मौजूद आइटम, SleepNight सीधे स्क्रीन पर मौजूद आइटम पर मैप करता है.

[असल डेटा] -> [अडैप्टर व्यू]

[0: हेडर] -> [0: हेडर]

[1: SleepNight] -> [1: SleepNight]

[2: SleepNight] -> [2: SleepNight]

[3: SleepNight] -> [3: SleepNight]

हर तरीके के अपने फ़ायदे और कमियां हैं. डेटासेट बदलने से # बाकी अडैप्टर कोड में बहुत ज़्यादा बदलाव नहीं होता है. साथ ही, आप डेटा की सूची में हेर-फेर करके हेडर लॉजिक जोड़ सकते हैं. दूसरी ओर, हेडर के लिए इंडेक्स की जांच करके किसी अलग ViewHolder का इस्तेमाल करने से, हेडर के लेआउट को ज़्यादा आज़ादी मिलती है. इसकी मदद से, अडैप्टर यह भी मैनेज कर सकते हैं कि बैक अप डेटा में बदलाव किए बिना, व्यू में डेटा कैसे बदले.

इस कोडलैब में आप सूची की शुरुआत में एक हेडर दिखाने के लिए, अपना RecyclerView अपडेट करते हैं. इस मामले में, आपका ऐप्लिकेशन डेटा आइटम के हेडर की तुलना में एक अलग ViewHolder का इस्तेमाल करेगा. ऐप्लिकेशन, सूची के इंडेक्स की जांच करके तय करेगा कि किस ViewHolder का इस्तेमाल करना है.

पहला चरण: DataItem क्लास बनाना

आइटम के प्रकार को ऐब्स्ट्रैक्ट करने और अडैप्टर को "items&कोटेशन की सुविधा देने दें; इसके लिए, आप डेटा होल्डर क्लास बना सकते हैं, जो SleepNight या Header को दिखाती है. इसके बाद, आपके डेटासेट में डेटा होल्डर आइटम की सूची शामिल होगी.

आप GitHub से स्टार्टर ऐप्लिकेशन पा सकते हैं या पिछले कोडलैब में बनाए गए SleepTracker ऐप्लिकेशन का इस्तेमाल जारी रख सकते हैं.

  1. GitHub से RecyclerViewHeaders-Starter कोड डाउनलोड करें. RecyclerViewHeaders-Starter डायरेक्ट्री में, इस कोडलैब के लिए ज़रूरी SleepTracker ऐप्लिकेशन का स्टार्टर वर्शन ज़रूरी है. अगर आप चाहें, तो पिछले कोडलैब से पूरे किए गए ऐप्लिकेशन का इस्तेमाल जारी रख सकते हैं.
  2. SleepNightAdapter.kt खोलें.
  3. SleepNightListener क्लास के नीचे, टॉप लेवल पर, DataItem नाम की sealed क्लास बताएं जो डेटा का एक आइटम दिखाता है.

    sealed क्लास में क्लोज़्ड टाइप होता है. इसका मतलब है कि DataItem की सभी सब-क्लास को इस फ़ाइल में बताया जाना चाहिए. इस वजह से, सब-क्लास की संख्या कंपाइलर के तौर पर जानी जाती है. आपके कोड के किसी दूसरे हिस्से के लिए DataItem का नया टाइप तय नहीं किया जा सकता. इससे आपका अडैप्टर खराब हो सकता है.
sealed class DataItem {

 }
  1. DataItem क्लास के मुख्य हिस्से में, दो क्लास तय करें जो अलग-अलग तरह के डेटा आइटम को दिखाती हैं. पहला SleepNightItem है, जो एक SleepNight के आस-पास रैपर है, इसलिए इसे sleepNight कहा जाता है. इसे सील की गई कक्षा का हिस्सा बनाने के लिए, इसका समय DataItem बढ़ाएं.
data class SleepNightItem(val sleepNight: SleepNight): DataItem()
  1. दूसरी क्लास, हेडर दिखाने के लिए Header है. हेडर पर कोई डेटा नहीं है, इसलिए आप उसे object के तौर पर बता सकते हैं. इसका मतलब है कि Header कभी भी सिर्फ़ एक इंस्टेंस में गिना जाएगा. फिर से, इसे DataItem तक बढ़ाएं.
object Header: DataItem()
  1. DataItem के अंदर, क्लास के स्तर पर id नाम की abstract Long प्रॉपर्टी तय करें. जब अडैप्टर यह पता लगाने के लिए DiffUtil का इस्तेमाल करता है कि आइटम में बदलाव हुआ है या नहीं, तो DiffItemCallback को हर आइटम का आईडी जानने की ज़रूरत होती है. आपको गड़बड़ी का मैसेज दिखेगा, क्योंकि SleepNightItem और Header को एब्स्ट्रैक्ट प्रॉपर्टी id को ओवरराइड करना होगा.
abstract val id: Long
  1. nightId को लौटाने के लिए, SleepNightItem में id को ओवरराइड करें.
override val id = sleepNight.nightId
  1. Header में, Long.MIN_VALUE लौटाने के लिए id को बदलें. यह बहुत छोटा नंबर है (63 की घात 63 है). इसलिए, यह कभी भी nightId के मौजूद होने पर कोई टकराव नहीं करेगा.
override val id = Long.MIN_VALUE
  1. आपका तैयार कोड इस तरह दिखना चाहिए कि आपका ऐप्लिकेशन बिना किसी गड़बड़ी के बन जाए.
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 बनाना

  1. हेडर रिसॉर्स के लिए लेआउट बनाएं, ताकि वह हेडर.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" />
  1. "Sleep Results" को स्ट्रिंग के संसाधन में निकालें और उसे header_text कॉल करें.
<string name="header_text">Sleep Results</string>
  1. SleepNightAdapter के अंदर, SleepNightAdapter.kt में ViewHolder क्लास के ऊपर, एक नई TextViewHolder क्लास बनाएं. यह क्लास textview.xml लेआउट को इनफ़्लेट करती है और TextViewHolder इंस्टेंस दिखाती है. आपने पहले #&939 किया है, इसलिए यह कोड आपको है. आपको और #39; को 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 के साथ काम करने के बजाय, यह ज़रूरी है कि वह किसी भी तरह के व्यू होल्डर का इस्तेमाल कर पाए.

तय करें कि आइटम किस तरह के हैं

  1. SleepNightAdapter.kt में, टॉप लेवल पर, import स्टेटमेंट के नीचे और SleepNightAdapter से ज़्यादा के व्यू के लिए दो कॉन्सटेंट तय करें.

    RecyclerView को हर आइटम के व्यू टाइप की पहचान करनी होगी, ताकि वह सही तरीके से व्यू होल्डर असाइन कर सके.
    private val ITEM_VIEW_TYPE_HEADER = 0
    private val ITEM_VIEW_TYPE_ITEM = 1
  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 की परिभाषा अपडेट करें

  1. SleepNightAdapter की जानकारी में, ListAdapter के पहले तर्क को SleepNight से DataItem में अपडेट करें.
  2. SleepNightAdapter की परिभाषा में, ListAdapter के दूसरे सामान्य आर्ग्युमेंट को SleepNightAdapter.ViewHolder से RecyclerView.ViewHolder में बदलें. आपको ज़रूरी अपडेट के लिए कुछ गड़बड़ियां दिखेंगी और आपकी कक्षा का हेडर नीचे दिखाया जाना चाहिए.
class SleepNightAdapter(val clickListener: SleepNightListener):
       ListAdapter<DataItem, RecyclerView.ViewHolder>(SleepNightDiffCallback()) {

onCreateViewHolder() अपडेट करना

  1. RecyclerView.ViewHolder लौटाने के लिए, onCreateViewHolder() का हस्ताक्षर बदलें.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder
  1. हर आइटम टाइप के लिए, सही व्यू होल्डर की जांच करने और उसे रिटर्न करने के लिए, 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() अपडेट करना

  1. onBindViewHolder() के पैरामीटर टाइप को ViewHolder से बदलकर RecyclerView.ViewHolder करें.
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int)
  1. अगर होल्डर ViewHolder है, तो सिर्फ़ व्यू होल्डर को डेटा असाइन करने के लिए एक शर्त जोड़ें.
        when (holder) {
            is ViewHolder -> {...}
  1. 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 कॉलबैक अपडेट करें

  1. SleepNight के बजाय नई DataItem क्लास का इस्तेमाल करने के लिए, SleepNightDiffCallback में दिए गए तरीके बदलें. नीचे दिए गए कोड के मुताबिक, लिंट की चेतावनी को रोकें.
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
    }
}

हेडर जोड़ना और सबमिट करना

  1. SleepNightAdapter में onCreateViewHolder() के नीचे, किसी फ़ंक्शन addHeaderAndSubmitList() को परिभाषित करें, जैसा कि नीचे दिखाया गया है. यह फ़ंक्शन SleepNight की सूची लेता है. अपनी सूची सबमिट करने के लिए, आप submitList() की मदद से, ListAdapter का इस्तेमाल करने के बजाय, एक हेडर जोड़ने और फिर सूची सबमिट करने के लिए, इस फ़ंक्शन का इस्तेमाल करेंगे.
fun addHeaderAndSubmitList(list: List<SleepNight>?) {}
  1. addHeaderAndSubmitList() में, अगर पास की गई सूची null है, तो सिर्फ़ एक हेडर दिखाएं. अगर नहीं, तो हेडर को सूची के सबसे ऊपर जोड़ें और फिर सूची सबमिट करें.
val items = when (list) {
                null -> listOf(DataItem.Header)
                else -> listOf(DataItem.Header) + list.map { DataItem.SleepNightItem(it) }
            }
submitList(items)
  1. SleepTrackerFragment.kt खोलें और कॉल को submitList() से addHeaderAndSubmitList() में बदलें.
  1. अपना ऐप्लिकेशन चलाएं और देखें कि नींद के सामान की सूची में आपका हेडर, पहले आइटम के तौर पर कैसे दिखता है.

इस ऐप्लिकेशन के लिए दो चीज़ें ठीक करनी होंगी. इनमें से एक चीज़ दिख रही है और एक नहीं.

  • हेडर, सबसे ऊपर बाएं कोने में दिखता है और आसानी से अलग नहीं किया जा सकता.
  • यह एक हेडर वाली छोटी सूची के लिए कोई मायने नहीं रखता, लेकिन यूज़र इंटरफ़ेस (यूआई) थ्रेड पर, addHeaderAndSubmitList() में हेर-फेर नहीं करना चाहिए. यह तय करने के लिए कि आइटम कहां डाले जाने चाहिए, सैकड़ों आइटम, एक से ज़्यादा हेडर, और तर्क वाली सूची बनाएं. यह काम कोरूटीन से जुड़ा है.

कोरूटीन इस्तेमाल करने के लिए, addHeaderAndSubmitList() बदलें:

  1. SleepNightAdapter क्लास के अंदर सबसे ऊपर के लेवल पर, Dispatchers.Default के साथ CoroutineScope तय करें.
private val adapterScope = CoroutineScope(Dispatchers.Default)
  1. 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)
            }
        }
    }
  1. आपका कोड बन जाना चाहिए और चलना चाहिए. आपको कोई अंतर नहीं दिखेगा.

फ़िलहाल, हेडर ग्रिड में मौजूद दूसरे आइटम की चौड़ाई ही है. पूरा ग्रिड एक स्पैन की चौड़ाई के तीन आइटम को हॉरिज़ॉन्टली फ़िट करता है, इसलिए हेडर को हॉरिज़ॉन्टल तीन स्पैन का इस्तेमाल करना चाहिए.

हेडर की चौड़ाई ठीक करने के लिए, आपको GridLayoutManager को यह बताना होगा कि सभी कॉलम में डेटा कब तक फैला होना चाहिए. आप GridLayoutManager पर SpanSizeLookup को कॉन्फ़िगर करके, ऐसा कर सकते हैं. यह एक कॉन्फ़िगरेशन ऑब्जेक्ट है, जिसका इस्तेमाल GridLayoutManager यह तय करने के लिए करता है कि सूची के हर आइटम के लिए, कितने स्पैन का इस्तेमाल किया जाता है.

  1. SleepTrackerFragment.kt खोलें.
  2. वह कोड ढूंढें जहां आप onCreateView() के आखिर में, manager तय करते हैं.
val manager = GridLayoutManager(activity, 3)
  1. manager के नीचे, manager.spanSizeLookup दिखाएं, जैसा कि दिखाया गया है. आपको object बनाना होगा, क्योंकि setSpanSizeLookup यह lambda को नहीं लेता है. Kotlin में object बनाने के लिए, object : classname टाइप करें, फिर इस मामले में GridLayoutManager.SpanSizeLookup.
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
}
  1. आपको कंस्ट्रक्टर को कॉल करने में कंपाइल वाली गड़बड़ी मिल सकती है. अगर आप ऐसा करते हैं, तो कंस्ट्रक्टर कॉल को लागू करने के लिए Option+Enter (Mac) या Alt+Enter (Windows) वाला इंटेंट मेन्यू खोलें.
  1. इसके बाद, आपको object पर गड़बड़ी का मैसेज दिखेगा. इसमें बताया जाएगा कि आपको तरीकों को बदलने की ज़रूरत है. इंटेंट मेन्यू खोलने के लिए, कर्सर को object पर रखें. इसके बाद, Option+Enter (Mac) या Alt+Enter (Windows) दबाएं. फिर, getSpanSize() तरीके को बदलें.
  1. getSpanSize() के मुख्य हिस्से में, हर पोज़िशन के लिए सही स्पैन साइज़ दिखाएं. जगह 0 का स्पैन साइज़ 3 है और दूसरी जगहों का स्पैन साइज़ 1 है. आपका पूरा हो गया कोड नीचे दिए गए कोड जैसा दिखना चाहिए:
    manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int) =  when (position) {
                0 -> 3
                else -> 1
            }
        }
  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"
  1. अपना ऐप्लिकेशन चलाएं. यह नीचे दिए गए स्क्रीनशॉट की तरह दिखना चाहिए.

बधाई हो! प्रक्रिया पूरी हो गई है.

Android Studio प्रोजेक्ट: RecyclerViewHeaders

  • आम तौर पर, हेडर एक ऐसा आइटम होता है जो सूची की चौड़ाई में फैला होता है और शीर्षक या सेपरेटर के तौर पर काम करता है. किसी आइटम के बारे में बताने के लिए सूची में एक हेडर हो सकता है. इसके अलावा, आइटम को ग्रुप करने और एक-दूसरे से अलग आइटम के लिए कई हेडर का इस्तेमाल किया जा सकता है.
  • RecyclerView, अलग-अलग तरह के आइटम को शामिल करने के लिए एक से ज़्यादा व्यू होल्डर का इस्तेमाल कर सकता है. उदाहरण के लिए, हेडर और सूची के आइटम.
  • हेडर जोड़ने का एक तरीका यह है कि आप उन इंडेक्स की जांच करके जिनमें आपका हेडर दिखाना है, किसी दूसरे ViewHolder का इस्तेमाल करें. हेडर का ट्रैक रखने की ज़िम्मेदारी Adapter की है.
  • हेडर जोड़ने का एक और तरीका, अपने डेटा ग्रिड के लिए बैकिंग डेटासेट (सूची) में बदलाव करना है. यह वही काम है जो आपने इस कोडलैब में किया था.

हेडर जोड़ने के ये मुख्य तरीके हैं:

  • हेडर या डेटा होल्ड कर सकने वाला DataItem बनाकर, अपनी सूची में डेटा एब्स्ट्रैक्ट करें.
  • अडैप्टर में हेडर के लिए लेआउट वाला व्यू होल्डर बनाएं.
  • किसी भी तरह के RecyclerView.ViewHolder का इस्तेमाल करने के लिए अडैप्टर और उसके तरीकों को अपडेट करें.
  • onCreateViewHolder() में, डेटा आइटम के लिए सही तरह का व्यू होल्डर दिखाएं.
  • DataItem क्लास के साथ काम करने के लिए, SleepNightDiffCallback अपडेट करें.
  • एक ऐसा addHeaderAndSubmitList() फ़ंक्शन बनाएं जो डेटासेट में हेडर जोड़ने के लिए कोरूटीन का इस्तेमाल करता हो. इसके बाद, submitList() को कॉल करता हो.
  • सिर्फ़ हेडर तीन स्पैन को बनाने के लिए, GridLayoutManager.SpanSizeLookup() लागू करें.

Udcity कोर्स:

Android डेवलपर दस्तावेज़:

इस सेक्शन में उन छात्र-छात्राओं के लिए गृहकार्य की असाइनमेंट की सूची दी गई है जो इस कोडलैब के ज़रिए एक शिक्षक की देखरेख में कोर्स में काम कर रहे हैं. यह क्रिएटर का काम #33 पर निर्भर करता है:

  • अगर ज़रूरी हो, तो होमवर्क असाइन करें.
  • छात्र-छात्राओं को होमवर्क के असाइनमेंट सबमिट करने के तरीके के बारे में बताएं.
  • होमवर्क असाइनमेंट को ग्रेड दें.

शिक्षक इन सुझावों का इस्तेमाल जितनी चाहें उतनी कम या ज़्यादा कर सकते हैं. साथ ही, उन्हें अपने हिसाब से कोई भी होमवर्क असाइन करना चाहिए.

अगर आप इस कोडलैब के ज़रिए खुद काम कर रहे हैं, तो बेझिझक इन होमवर्क असाइनमेंट का इस्तेमाल करें.

इन सवालों के जवाब दें

पहला सवाल

ViewHolder के बारे में इनमें से कौनसी बातें सही हैं?

▢ अडैप्टर, हेडर और कई तरह के डेटा को होल्ड करने के लिए, एक से ज़्यादा ViewHolder क्लास इस्तेमाल कर सकता है.

▢ आपके पास डेटा के लिए सिर्फ़ एक व्यू होल्डर और हेडर के लिए एक व्यू होल्डर हो सकता है.

▢ A RecyclerView में कई तरह के हेडर इस्तेमाल किए जा सकते हैं, लेकिन डेटा एक जैसा होना चाहिए.

▢ हेडर जोड़ते समय, आप हेडर को सही जगह पर डालने के लिए RecyclerView सब-क्लास करते हैं.

दूसरा सवाल

आपको RecyclerView के साथ कोरूटीन का इस्तेमाल कब करना चाहिए? सभी सही जवाब चुनें.

▢ कभी नहीं. RecyclerView, एक यूज़र इंटरफ़ेस (यूआई) एलिमेंट है. कोरूटीन इस्तेमाल नहीं करना चाहिए.

▢ लंबे समय तक चलने वाले उन टास्क के लिए कोरूटीन का इस्तेमाल करें जो यूज़र इंटरफ़ेस (यूआई) को धीमा कर सकते हैं.

▢ सूची में बदलाव करने में लंबा समय लग सकता है और आपको हमेशा कोरूटीन इस्तेमाल करना चाहिए.

▢ मुख्य थ्रेड को ब्लॉक करने से बचने के लिए, सस्पेंड फ़ंक्शन के साथ कोरूटीन का इस्तेमाल करें.

तीसरा सवाल

ViewHolder के एक से ज़्यादा का इस्तेमाल करते समय, आपको इनमें से क्या करना पड़ता है?

ViewHolder में, ज़रूरत के मुताबिक बढ़ोतरी के लिए एक से ज़्यादा लेआउट फ़ाइलें उपलब्ध कराएं.

onCreateViewHolder() में डेटा आइटम के लिए, सही तरह के व्यू होल्डर का इस्तेमाल करें.

onBindViewHolder() में डेटा सिर्फ़ तब बाइंड करें, जब व्यू आइटम, डेटा आइटम के लिए सही तरह का व्यू होल्डर हो.

▢ किसी भी RecyclerView.ViewHolder को स्वीकार करने के लिए, अडैप्टर की कैटगरी के हस्ताक्षर को सामान्य बनाएं.

अगला लेसन शुरू करें: 8.1 इंटरनेट से डेटा लेना

इस कोर्स में दिए गए दूसरे कोडलैब के लिंक के लिए, Android Kotlin की बुनियादी बातें कोडलैब का लैंडिंग पेज देखें.