Android Kotlin Fundamentals 07.1: RecyclerView की बुनियादी बातें

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

परिचय

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

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

आपको इनके बारे में जानकारी होनी चाहिए:

  • ऐक्टिविटी, फ़्रैगमेंट, और व्यू का इस्तेमाल करके, बुनियादी यूज़र इंटरफ़ेस (यूआई) बनाना.
  • फ़्रैगमेंट के बीच नेविगेट करना और फ़्रैगमेंट के बीच डेटा पास करने के लिए, safeArgs का इस्तेमाल करना.
  • व्यू मॉडल, व्यू मॉडल फ़ैक्ट्री, ट्रांसफ़ॉर्मेशन, और LiveData और उनके ऑब्ज़र्वर का इस्तेमाल करना.
  • Room डेटाबेस बनाना, DAO बनाना, और इकाइयों को तय करना.
  • डेटाबेस के टास्क और लंबे समय तक चलने वाले अन्य टास्क के लिए, कोराउटीन का इस्तेमाल करना.

आपको क्या सीखने को मिलेगा

  • आइटम की सूची दिखाने के लिए, Adapter और ViewHolder के साथ RecyclerView का इस्तेमाल करने का तरीका.

आपको क्या करना होगा

  • पिछले सबक में इस्तेमाल किए गए TrackMySleepQuality ऐप्लिकेशन में बदलाव करें, ताकि नींद की क्वालिटी का डेटा दिखाने के लिए RecyclerView का इस्तेमाल किया जा सके.

इस कोडलैब में, आपको नींद की क्वालिटी को ट्रैक करने वाले ऐप्लिकेशन का RecyclerView हिस्सा बनाने का तरीका बताया जाएगा. यह ऐप्लिकेशन, समय के साथ नींद के डेटा को सेव करने के लिए Room डेटाबेस का इस्तेमाल करता है.

नीचे दिए गए डायग्राम में, स्लीप ट्रैकर ऐप्लिकेशन की दो स्क्रीन दिखाई गई हैं. इन्हें फ़्रैगमेंट के तौर पर दिखाया गया है.

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

यह ऐप्लिकेशन, यूज़र इंटरफ़ेस कंट्रोलर, ViewModel, और LiveData के साथ आसान आर्किटेक्चर का इस्तेमाल करता है. यह ऐप्लिकेशन, नींद के डेटा को सेव रखने के लिए Room डेटाबेस का भी इस्तेमाल करता है.

पहली स्क्रीन में नींद की रातों की सूची दिखती है. यह काम करती है, लेकिन अच्छी नहीं दिखती. यह ऐप्लिकेशन, टेक्स्ट व्यू के लिए टेक्स्ट स्ट्रिंग और क्वालिटी के लिए नंबर बनाने के लिए, मुश्किल फ़ॉर्मेटर का इस्तेमाल करता है. साथ ही, इस डिज़ाइन को बढ़ाया नहीं जा सकता. इस कोडलैब में इन सभी समस्याओं को ठीक करने के बाद, फ़ाइनल ऐप्लिकेशन में वही फ़ंक्शन काम करते हैं. साथ ही, मुख्य स्क्रीन ऐसी दिखती है:

Android में, डेटा की सूची या ग्रिड दिखाना, यूज़र इंटरफ़ेस (यूआई) के सबसे सामान्य टास्क में से एक है. सूचियां, आसान से लेकर बहुत जटिल तक हो सकती हैं. टेक्स्ट व्यू की सूची में, शॉपिंग लिस्ट जैसे सामान्य डेटा को दिखाया जा सकता है. जटिल सूची, जैसे कि छुट्टियों के लिए जगहों की एनोटेट की गई सूची में, उपयोगकर्ता को हेडर वाली स्क्रोलिंग ग्रिड में कई तरह की जानकारी दिख सकती है.

इन सभी इस्तेमाल के उदाहरणों के लिए, Android RecyclerView विजेट उपलब्ध कराता है.

RecyclerView का सबसे बड़ा फ़ायदा यह है कि यह बड़ी सूचियों के लिए बहुत कारगर है:

  • डिफ़ॉल्ट रूप से, RecyclerView सिर्फ़ उन आइटम को प्रोसेस या ड्रॉ करता है जो फ़िलहाल स्क्रीन पर दिख रहे हैं. उदाहरण के लिए, अगर आपकी सूची में एक हज़ार एलिमेंट हैं, लेकिन सिर्फ़ 10 एलिमेंट दिख रहे हैं, तो RecyclerView सिर्फ़ 10 आइटम को स्क्रीन पर दिखाने के लिए काम करता है. जब उपयोगकर्ता स्क्रोल करता है, तो RecyclerView यह पता लगाता है कि स्क्रीन पर कौनसे नए आइटम दिखने चाहिए. इसके बाद, उन आइटम को दिखाने के लिए ज़रूरी काम करता है.
  • जब कोई आइटम स्क्रोल करके स्क्रीन से हटा दिया जाता है, तो आइटम के व्यू रीसाइकल किए जाते हैं. इसका मतलब है कि आइटम में नया कॉन्टेंट जोड़ा गया है, जो स्क्रीन पर स्क्रोल होता है. इस RecyclerView व्यवहार से, प्रोसेस करने में लगने वाला समय काफ़ी बचता है. साथ ही, सूचियों को आसानी से स्क्रोल किया जा सकता है.
  • किसी आइटम में बदलाव होने पर, पूरी सूची को फिर से बनाने के बजाय, RecyclerView सिर्फ़ उस आइटम को अपडेट कर सकता है. जटिल आइटम की सूचियां दिखाते समय, इससे काफ़ी फ़ायदा मिलता है!

यहां दिए गए क्रम में, आपको दिखेगा कि एक व्यू में डेटा भर दिया गया है, ABC. इसके बाद, जब वह व्यू स्क्रीन से हट जाता है, तो RecyclerView नए डेटा के लिए व्यू का फिर से इस्तेमाल करता है, XYZ.

अडैप्टर पैटर्न

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

सॉफ़्टवेयर इंजीनियरिंग में ऐडैप्टर पैटर्न, किसी ऑब्जेक्ट को दूसरे एपीआई के साथ काम करने में मदद करता है. RecyclerView, ऐप्लिकेशन के डेटा को ऐसे फ़ॉर्मैट में बदलने के लिए अडैप्टर का इस्तेमाल करता है जिसे RecyclerView दिखा सके. इससे, ऐप्लिकेशन के डेटा को सेव करने और प्रोसेस करने के तरीके में कोई बदलाव नहीं होता. स्लीप-ट्रैकर ऐप्लिकेशन के लिए, एक ऐसा अडैप्टर बनाया जाता है जो Room डेटाबेस से मिले डेटा को ऐसे फ़ॉर्मैट में बदलता है जिसे RecyclerView दिखा सकता है. हालांकि, इस प्रोसेस में ViewModel में कोई बदलाव नहीं किया जाता.

RecyclerView लागू करना

अपने डेटा को RecyclerView में दिखाने के लिए, आपको इन चीज़ों की ज़रूरत होगी:

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

इस टास्क में, आपको अपनी लेआउट फ़ाइल में RecyclerView जोड़ना होगा. साथ ही, Adapter सेट अप करना होगा, ताकि RecyclerView को नींद का डेटा मिल सके.

पहला चरण: LayoutManager के साथ RecyclerView जोड़ना

इस चरण में, आपको fragment_sleep_tracker.xml फ़ाइल में मौजूद ScrollView को RecyclerView से बदलना होगा.

  1. GitHub से RecyclerViewFundamentals-Starter ऐप्लिकेशन डाउनलोड करें.
  2. ऐप्लिकेशन बनाएं और उसे चलाएं. देखें कि डेटा को सामान्य टेक्स्ट के तौर पर कैसे दिखाया जाता है.
  3. Android Studio में, Design टैब में fragment_sleep_tracker.xml लेआउट फ़ाइल खोलें.
  4. कॉम्पोनेंट ट्री पैनल में, ScrollView को मिटाएं. इस कार्रवाई से, ScrollView में मौजूद TextView भी मिट जाता है.
  5. पैलेट पैनल में, बाईं ओर मौजूद कॉम्पोनेंट टाइप की सूची में नीचे की ओर स्क्रोल करके कंटेनर ढूंढें. इसके बाद, इसे चुनें.
  6. पैलेट पैन से RecyclerView को खींचकर कॉम्पोनेंट ट्री पैन में छोड़ें. RecyclerView को ConstraintLayout में रखें.

  1. अगर कोई डायलॉग बॉक्स खुलता है और आपसे पूछा जाता है कि क्या आपको कोई डिपेंडेंसी जोड़नी है, तो ठीक है पर क्लिक करें. इससे Android Studio, आपकी Gradle फ़ाइल में recyclerview डिपेंडेंसी जोड़ देगा. इसमें कुछ सेकंड लग सकते हैं. इसके बाद, आपका ऐप्लिकेशन सिंक हो जाएगा.

  1. मॉड्यूल build.gradle फ़ाइल खोलें, सबसे नीचे तक स्क्रोल करें, और नई डिपेंडेंसी पर ध्यान दें. यह नीचे दिए गए कोड की तरह दिखती है:
implementation 'androidx.recyclerview:recyclerview:1.0.0'
  1. fragment_sleep_tracker.xml पर वापस स्विच करें.
  2. टेक्स्ट टैब में, यहां दिया गया RecyclerView कोड ढूंढें:
<androidx.recyclerview.widget.RecyclerView
   android:layout_width="match_parent"
   android:layout_height="match_parent" />
  1. RecyclerView को sleep_list का id दें.
android:id="@+id/sleep_list"
  1. RecyclerView को इस तरह से रखें कि वह ConstraintLayout के अंदर स्क्रीन के बाकी हिस्से को कवर करे. इसके लिए, RecyclerView के टॉप को Start बटन से, बॉटम को Clear बटन से, और हर साइड को पैरंट से कंस्ट्रेंट करें. लेआउट एडिटर या एक्सएमएल में, लेआउट की चौड़ाई और ऊंचाई को 0 डीपी पर सेट करें. इसके लिए, इस कोड का इस्तेमाल करें:
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toTopOf="@+id/clear_button"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/stop_button"
  1. RecyclerView एक्सएमएल में लेआउट मैनेजर जोड़ें. हर RecyclerView को एक लेआउट मैनेजर की ज़रूरत होती है. यह लेआउट मैनेजर, RecyclerView को बताता है कि सूची में आइटम को कैसे व्यवस्थित करना है. Android, LinearLayoutManager उपलब्ध कराता है. यह डिफ़ॉल्ट रूप से, आइटम को पूरी चौड़ाई वाली लाइनों की वर्टिकल सूची में दिखाता है.
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
  1. डिज़ाइन टैब पर जाएं. देखें कि जोड़ी गई पाबंदियों की वजह से, RecyclerView को बड़ा करके, उपलब्ध जगह के हिसाब से कर दिया गया है.

दूसरा चरण: लिस्ट आइटम लेआउट और टेक्स्ट व्यू होल्डर बनाना

RecyclerView सिर्फ़ एक कंटेनर है. इस चरण में, RecyclerView में दिखाए जाने वाले आइटम के लिए लेआउट और बुनियादी ढांचा बनाया जाता है.

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

  1. text_item_view.xml नाम की लेआउट फ़ाइल बनाएं. रूट एलिमेंट के तौर पर किसी भी एलिमेंट का इस्तेमाल किया जा सकता है, क्योंकि आपको टेंप्लेट कोड को बदलना होगा.
  2. text_item_view.xml में, दिया गया पूरा कोड मिटाएं.
  3. शुरुआत और आखिर में 16dp पैडिंग और 24sp के टेक्स्ट साइज़ वाला TextView जोड़ें. चौड़ाई को पैरंट के हिसाब से सेट करें और ऊंचाई को कॉन्टेंट के हिसाब से रैप करें. यह व्यू RecyclerView में दिखता है. इसलिए, आपको व्यू को ViewGroup में रखने की ज़रूरत नहीं है.
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:textSize="24sp"
    android:paddingStart="16dp"
    android:paddingEnd="16dp"
    android:layout_width="match_parent"       
    android:layout_height="wrap_content" />
  1. Util.kt खोलें. सबसे नीचे तक स्क्रोल करें और यहां दी गई डेफ़िनिशन जोड़ें. इससे TextItemViewHolder क्लास बन जाएगी. कोड को फ़ाइल में सबसे नीचे, आखिरी क्लोज़िंग ब्रेस के बाद रखें. कोड को Util.kt में रखा जाता है, क्योंकि यह व्यू होल्डर कुछ समय के लिए होता है और इसे बाद में बदल दिया जाता है.
class TextItemViewHolder(val textView: TextView): RecyclerView.ViewHolder(textView)
  1. अगर आपसे कहा जाए, तो android.widget.TextView और androidx.recyclerview.widget.RecyclerView इंपोर्ट करें.

तीसरा चरण: SleepNightAdapter बनाएं

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

  1. sleeptracker पैकेज में, SleepNightAdapter नाम की नई Kotlin क्लास बनाएं.
  2. SleepNightAdapter क्लास को RecyclerView.Adapter एक्सटेंड करें. इस क्लास को SleepNightAdapter कहा जाता है, क्योंकि यह SleepNight ऑब्जेक्ट को ऐसी चीज़ में बदलता है जिसका इस्तेमाल RecyclerView कर सकता है. अडैप्टर को यह पता होना चाहिए कि किस व्यू होल्डर का इस्तेमाल करना है. इसलिए, TextItemViewHolder पास करें. जब आपसे कहा जाए, तब ज़रूरी कॉम्पोनेंट इंपोर्ट करें. इसके बाद, आपको एक गड़बड़ी दिखेगी, क्योंकि लागू करने के लिए कुछ तरीके ज़रूरी हैं.
class SleepNightAdapter: RecyclerView.Adapter<TextItemViewHolder>() {}
  1. SleepNightAdapter के टॉप लेवल पर, डेटा को सेव करने के लिए listOf SleepNight वैरिएबल बनाएं.
var data =  listOf<SleepNight>()
  1. SleepNightAdapter में, getItemCount() को बदलें, ताकि data में नींद की रातों की सूची का साइज़ दिखाया जा सके. RecyclerView को यह पता होना चाहिए कि अडैप्टर के पास दिखाने के लिए कितने आइटम हैं. इसके लिए, वह getItemCount() को कॉल करता है.
override fun getItemCount() = data.size
  1. SleepNightAdapter में, onBindViewHolder() फ़ंक्शन को ओवरराइड करें. इसके लिए, यहां दिया गया तरीका अपनाएं.

    onBindViewHolder() फ़ंक्शन को RecyclerView कॉल करता है, ताकि सूची में मौजूद किसी आइटम का डेटा, तय की गई जगह पर दिखाया जा सके. इसलिए, onBindViewHolder() तरीके में दो आर्ग्युमेंट होते हैं: व्यू होल्डर और बाइंड करने के लिए डेटा की पोज़िशन. इस ऐप्लिकेशन के लिए, होल्डर TextItemViewHolder है. साथ ही, इसकी पोज़िशन सूची में इसकी पोज़िशन है.
override fun onBindViewHolder(holder: TextItemViewHolder, position: Int) {
}
  1. onBindViewHolder() में, डेटा में किसी दी गई पोज़िशन पर मौजूद एक आइटम के लिए वैरिएबल बनाएं.
 val item = data[position]
  1. आपने जो ViewHolder बनाया है उसमें textView नाम की प्रॉपर्टी है. onBindViewHolder() के अंदर, textView के text को नींद की क्वालिटी के हिसाब से सेट करें. इस कोड में सिर्फ़ संख्याओं की सूची दिखती है. हालांकि, इस आसान उदाहरण से यह पता चलता है कि अडैप्टर, व्यू होल्डर में और स्क्रीन पर डेटा कैसे दिखाता है.
holder.textView.text = item.sleepQuality.toString()
  1. SleepNightAdapter में, onCreateViewHolder() को बदलें और लागू करें. इसे तब कॉल किया जाता है, जब RecyclerView को किसी आइटम को दिखाने के लिए व्यू होल्डर की ज़रूरत होती है.

    यह फ़ंक्शन दो पैरामीटर लेता है और ViewHolder दिखाता है. parent पैरामीटर, व्यू ग्रुप होता है. इसमें व्यू होल्डर होता है. यह हमेशा RecyclerView होता है. viewType पैरामीटर का इस्तेमाल तब किया जाता है, जब एक ही RecyclerView में कई व्यू मौजूद हों. उदाहरण के लिए, अगर आपने टेक्स्ट व्यू, इमेज, और वीडियो की सूची को एक ही RecyclerView में रखा है, तो onCreateViewHolder() फ़ंक्शन को यह पता होना चाहिए कि किस तरह के व्यू का इस्तेमाल करना है.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TextItemViewHolder {
}
  1. onCreateViewHolder() में, LayoutInflater का इंस्टेंस बनाएं.

    लेआउट इन्फ़्लेटर को पता होता है कि एक्सएमएल लेआउट से व्यू कैसे बनाए जाते हैं. context में, व्यू को सही तरीके से बढ़ाने के बारे में जानकारी दी गई है. रीसाइक्लर व्यू के अडैप्टर में, हमेशा parent व्यू ग्रुप का कॉन्टेक्स्ट पास किया जाता है. यह RecyclerView होता है.
val layoutInflater = LayoutInflater.from(parent.context)
  1. onCreateViewHolder() में, view बनाएं. इसके लिए, layoutinflater को इसे बड़ा करने के लिए कहें.

    व्यू के लिए एक्सएमएल लेआउट और व्यू के लिए parent व्यू ग्रुप पास करें. तीसरा बूलियन आर्ग्युमेंट attachToRoot है. इस आर्ग्युमेंट को false होना चाहिए, क्योंकि RecyclerView इस आइटम को व्यू हैरारकी में जोड़ता है.
val view = layoutInflater
       .inflate(R.layout.text_item_view, parent, false) as TextView
  1. onCreateViewHolder() में, view का इस्तेमाल करके बनाई गई TextItemViewHolder को वापस पाएं.
return TextItemViewHolder(view)
  1. data में बदलाव होने पर, अडैप्टर को RecyclerView को इसकी सूचना देनी होगी. ऐसा इसलिए, क्योंकि RecyclerView को डेटा के बारे में कोई जानकारी नहीं होती. इसे सिर्फ़ उन व्यू होल्डर के बारे में पता होता है जो अडैप्टर इसे देता है.

    RecyclerView को यह बताने के लिए कि दिखाए जा रहे डेटा में बदलाव हुआ है, SleepNightAdapter क्लास में सबसे ऊपर मौजूद data वैरिएबल में कस्टम सेटर जोड़ें. सेटर में, data को नई वैल्यू दें. इसके बाद, notifyDataSetChanged() को कॉल करें, ताकि नए डेटा के साथ सूची को फिर से बनाया जा सके.
var data =  listOf<SleepNight>()
   set(value) {
       field = value
       notifyDataSetChanged()
   }

चौथा चरण: RecyclerView को अडैप्टर के बारे में बताना

RecyclerView को उस अडैप्टर के बारे में पता होना चाहिए जिसका इस्तेमाल व्यू होल्डर पाने के लिए किया जाता है.

  1. SleepTrackerFragment.kt खोलें.
  2. onCreateview() में, अडैप्टर बनाएं. इस कोड को ViewModel मॉडल बनाने के बाद और return स्टेटमेंट से पहले रखें.
val adapter = SleepNightAdapter()
  1. adapter को RecyclerView से जोड़ें.
binding.sleepList.adapter = adapter
  1. binding ऑब्जेक्ट को अपडेट करने के लिए, अपने प्रोजेक्ट को क्लीन करें और फिर से बनाएं.

    अगर आपको अब भी binding.sleepList या binding.FragmentSleepTrackerBinding से जुड़ी गड़बड़ियां दिखती हैं, तो कैश मेमोरी को अमान्य करें और फिर से शुरू करें. (फ़ाइल > कैश मेमोरी अमान्य करें / फिर से शुरू करें को चुनें.)

    अगर अब ऐप्लिकेशन चलाया जाता है, तो कोई गड़बड़ी नहीं होती. हालांकि, शुरू करें और फिर बंद करें पर टैप करने पर, आपको कोई डेटा नहीं दिखेगा.

पांचवां चरण: अडैप्टर में डेटा पाना

अब तक आपके पास एक अडैप्टर है. साथ ही, अडैप्टर से RecyclerView में डेटा पाने का तरीका भी है. अब आपको ViewModel से डेटा को अडैप्टर में भेजना होगा.

  1. SleepTrackerViewModel खोलें.
  2. nights वैरिएबल ढूंढें. इसमें नींद से जुड़ी सभी रातें सेव होती हैं. यही डेटा दिखाना होता है. nights वैरिएबल को डेटाबेस पर getAllNights() को कॉल करके सेट किया जाता है.
  3. private को nights से हटाएं, क्योंकि आपको एक ऐसा ऑब्ज़र्वर बनाना है जिसे इस वैरिएबल को ऐक्सेस करने की ज़रूरत है. आपका एलान कुछ ऐसा दिखना चाहिए:
val nights = database.getAllNights()
  1. database पैकेज में जाकर, SleepDatabaseDao खोलें.
  2. getAllNights() फ़ंक्शन ढूंढें. ध्यान दें कि यह फ़ंक्शन, SleepNight वैल्यू की सूची को LiveData के तौर पर दिखाता है. इसका मतलब है कि nights वैरिएबल में LiveData शामिल है, जिसे Room अपडेट करता रहता है. साथ ही, nights में बदलाव होने पर आपको इसकी जानकारी मिल सकती है.
  3. SleepTrackerFragment खोलें.
  4. onCreateView() में, adapter बनाने के बाद, nights वैरिएबल पर एक ऑब्ज़र्वर बनाएं.

    लाइफ़साइकल के मालिक के तौर पर फ़्रैगमेंट का viewLifecycleOwner उपलब्ध कराकर, यह पक्का किया जा सकता है कि यह ऑब्ज़र्वर सिर्फ़ तब चालू हो, जब RecyclerView स्क्रीन पर हो.
sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
   })
  1. ऑब्ज़र्वर में, जब भी आपको nights के लिए कोई नॉन-नल वैल्यू मिलती है, तो उस वैल्यू को अडैप्टर के data को असाइन करें. ऑब्ज़र्वर और डेटा सेट करने के लिए, यह पूरा कोड है:
sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
   it?.let {
       adapter.data = it
   }
})
  1. अपना कोड बनाएं और उसे चलाएं.

    अगर आपका अडैप्टर काम कर रहा है, तो आपको नींद की क्वालिटी के नंबर, सूची के तौर पर दिखेंगे. बाईं ओर दिए गए स्क्रीनशॉट में, शुरू करें पर टैप करने के बाद -1 दिखता है. दाईं ओर मौजूद स्क्रीनशॉट में, बंद करें पर टैप करने और क्वालिटी रेटिंग चुनने के बाद, नींद की क्वालिटी का अपडेट किया गया नंबर दिखाया गया है.

छठा चरण: जानें कि व्यू होल्डर को कैसे रीसाइकल किया जाता है

RecyclerView recycles व्यू होल्डर, इसका मतलब है कि यह उनका फिर से इस्तेमाल करता है. जब कोई व्यू स्क्रीन से हट जाता है, तो RecyclerView उस व्यू का इस्तेमाल, स्क्रीन पर दिखने वाले व्यू के लिए करता है.

इन व्यू होल्डर को रीसाइकल किया जाता है. इसलिए, पक्का करें कि onBindViewHolder() उन सभी बदलावों को सेट या रीसेट करता हो जो पिछले आइटम ने व्यू होल्डर पर सेट किए थे.

उदाहरण के लिए, व्यू होल्डर में मौजूद टेक्स्ट का रंग लाल पर सेट किया जा सकता है. इन व्यू होल्डर में, एक या उससे कम क्वालिटी रेटिंग होती है. साथ ही, ये खराब नींद को दिखाते हैं.

  1. SleepNightAdapter क्लास में, onBindViewHolder() के आखिर में यह कोड जोड़ें.
if (item.sleepQuality <= 1) {
   holder.textView.setTextColor(Color.RED) // red
}
  1. ऐप्लिकेशन चलाएं.
  2. नींद की खराब क्वालिटी का कुछ डेटा जोड़ने पर, संख्या लाल रंग की हो जाती है.
  3. नींद की क्वालिटी के लिए ज़्यादा रेटिंग तब तक जोड़ें, जब तक आपको स्क्रीन पर लाल रंग का बड़ा नंबर न दिखे.

    RecyclerView व्यू होल्डर का फिर से इस्तेमाल करता है. इसलिए, यह आखिर में ज़्यादा रेटिंग के लिए, लाल रंग के किसी व्यू होल्डर का फिर से इस्तेमाल करता है. ज़्यादा रेटिंग को गलती से लाल रंग में दिखाया गया है.

  1. इस समस्या को ठीक करने के लिए, else स्टेटमेंट जोड़ें. इससे क्वालिटी एक से कम या उसके बराबर न होने पर, रंग को काला पर सेट किया जा सकेगा.

    दोनों शर्तों के साफ़ तौर पर मौजूद होने पर, व्यू होल्डर हर आइटम के लिए टेक्स्ट के सही रंग का इस्तेमाल करेगा.
if (item.sleepQuality <= 1) {
   holder.textView.setTextColor(Color.RED) // red
} else {
   // reset
   holder.textView.setTextColor(Color.BLACK) // black
}
  1. ऐप्लिकेशन चलाएं. संख्याओं का रंग हमेशा सही होना चाहिए.

बधाई हो! अब आपके पास पूरी तरह से काम करने वाला बेसिक RecyclerView है.

इस टास्क में, आपको सामान्य व्यू होल्डर को ऐसे व्यू होल्डर से बदलना है जो नींद से जुड़ी रात की ज़्यादा जानकारी दिखा सके.

आपने Util.kt में जो सामान्य ViewHolder जोड़ा है वह सिर्फ़ TextView को TextItemViewHolder में रैप करता है.

class TextItemViewHolder(val textView: TextView): RecyclerView.ViewHolder(textView)

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

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

पहला चरण: आइटम का लेआउट बनाना

इस चरण में, आपको एक आइटम के लिए लेआउट फ़ाइल बनानी होती है. लेआउट में, नींद की क्वालिटी के लिए ConstraintLayout, नींद की अवधि के लिए ImageView, और क्वालिटी के लिए टेक्स्ट के तौर पर TextView शामिल है.TextView आपने पहले भी लेआउट बनाए हैं. इसलिए, दिए गए XML कोड को कॉपी करके चिपकाएं.

  1. नई लेआउट रिसॉर्स फ़ाइल बनाएं और उसका नाम list_item_sleep_night रखें.
  2. फ़ाइल में मौजूद पूरे कोड को यहां दिए गए कोड से बदलें. इसके बाद, अभी बनाए गए लेआउट के बारे में जानें.
<?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="wrap_content">

   <ImageView
       android:id="@+id/quality_image"
       android:layout_width="@dimen/icon_size"
       android:layout_height="60dp"
       android:layout_marginStart="16dp"
       android:layout_marginTop="8dp"
       android:layout_marginBottom="8dp"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent"
       tools:srcCompat="@drawable/ic_sleep_5" />

   <TextView
       android:id="@+id/sleep_length"
       android:layout_width="0dp"
       android:layout_height="20dp"
       android:layout_marginStart="8dp"
       android:layout_marginTop="8dp"
       android:layout_marginEnd="16dp"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toEndOf="@+id/quality_image"
       app:layout_constraintTop_toTopOf="@+id/quality_image"
       tools:text="Wednesday" />

   <TextView
       android:id="@+id/quality_string"
       android:layout_width="0dp"
       android:layout_height="20dp"
       android:layout_marginTop="8dp"
       app:layout_constraintEnd_toEndOf="@+id/sleep_length"
       app:layout_constraintHorizontal_bias="0.0"
       app:layout_constraintStart_toStartOf="@+id/sleep_length"
       app:layout_constraintTop_toBottomOf="@+id/sleep_length"
       tools:text="Excellent!!!" />
</androidx.constraintlayout.widget.ConstraintLayout>
  1. Android Studio में Design टैब पर जाएं. डिज़ाइन व्यू में, आपका लेआउट नीचे बाईं ओर दिए गए स्क्रीनशॉट की तरह दिखता है. ब्लूप्रिंट व्यू में, यह दाईं ओर मौजूद स्क्रीनशॉट की तरह दिखता है.

दूसरा चरण: ViewHolder बनाना

  1. SleepNightAdapter.kt खोलें.
  2. SleepNightAdapter के अंदर ViewHolder नाम की एक क्लास बनाएं और उसे RecyclerView.ViewHolder तक बढ़ाएं.
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){}
  1. ViewHolder में, व्यू के रेफ़रंस पाएं. आपको उन व्यू का रेफ़रंस देना होगा जिन्हें यह ViewHolder अपडेट करेगा. हर बार इस ViewHolder को बाइंड करने के लिए, आपको इमेज और दोनों टेक्स्ट व्यू ऐक्सेस करने होंगे. (बाद में, डेटा बाइंडिंग का इस्तेमाल करने के लिए इस कोड को बदला जा सकता है.)
val sleepLength: TextView = itemView.findViewById(R.id.sleep_length)
val quality: TextView = itemView.findViewById(R.id.quality_string)
val qualityImage: ImageView = itemView.findViewById(R.id.quality_image)

तीसरा चरण: SleepNightAdapter में ViewHolder का इस्तेमाल करना

  1. SleepNightAdapter की परिभाषा में, TextItemViewHolder के बजाय, अभी-अभी बनाए गए SleepNightAdapter.ViewHolder का इस्तेमाल करें.
class SleepNightAdapter: RecyclerView.Adapter<SleepNightAdapter.ViewHolder>() {

onCreateViewHolder() को अपडेट करें:

  1. ViewHolder वापस पाने के लिए, onCreateViewHolder() का हस्ताक्षर बदलें.
  2. सही लेआउट रिसॉर्स list_item_sleep_night का इस्तेमाल करने के लिए, लेआउट इन्फ़्लेटर बदलें.
  3. TextView पर कास्ट करने की सुविधा बंद करो.
  4. TextItemViewHolder के बजाय, ViewHolder दिखाएं.

    यहां अपडेट किया गया onCreateViewHolder() फ़ंक्शन दिया गया है:
    override fun onCreateViewHolder(
            parent: ViewGroup, viewType: Int): ViewHolder {
        val layoutInflater = 
            LayoutInflater.from(parent.context)
        val view = layoutInflater
                .inflate(R.layout.list_item_sleep_night, 
                         parent, false)
        return ViewHolder(view)
    }

onBindViewHolder() को अपडेट करें:

  1. onBindViewHolder() के सिग्नेचर में बदलाव करें, ताकि holder पैरामीटर TextItemViewHolder के बजाय ViewHolder हो.
  2. onBindViewHolder() में, item की परिभाषा को छोड़कर, बाकी सभी कोड मिटाएं.
  3. एक val res तय करें, जो इस व्यू के लिए resources का रेफ़रंस रखता हो.
val res = holder.itemView.context.resources
  1. sleepLength टेक्स्ट व्यू के टेक्स्ट को अवधि पर सेट करें. नीचे दिए गए कोड को कॉपी करें. यह कोड, फ़ॉर्मैटिंग फ़ंक्शन को कॉल करता है. यह फ़ंक्शन, स्टार्टर कोड के साथ उपलब्ध कराया जाता है.
holder.sleepLength.text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, res)
  1. इससे एक गड़बड़ी का मैसेज दिखता है, क्योंकि convertDurationToFormatted() को तय करना ज़रूरी है. Util.kt खोलें और कोड के साथ-साथ उससे जुड़े इंपोर्ट के लिए, टिप्पणी हटाने का निशान हटाएं. (कोड > लाइन के साथ टिप्पणी करें चुनें.)
  2. onBindViewHolder() में वापस जाकर, क्वालिटी सेट करने के लिए convertNumericQualityToString() का इस्तेमाल करें.
holder.quality.text= convertNumericQualityToString(item.sleepQuality, res)
  1. आपको इन फ़ंक्शन को मैन्युअल तरीके से इंपोर्ट करना पड़ सकता है.
import com.example.android.trackmysleepquality.convertDurationToFormatted
import com.example.android.trackmysleepquality.convertNumericQualityToString
  1. क्वालिटी के लिए सही आइकॉन सेट करें. स्टार्टर कोड में, आपके लिए नया ic_sleep_active आइकॉन दिया गया है.
holder.qualityImage.setImageResource(when (item.sleepQuality) {
   0 -> R.drawable.ic_sleep_0
   1 -> R.drawable.ic_sleep_1
   2 -> R.drawable.ic_sleep_2
   3 -> R.drawable.ic_sleep_3
   4 -> R.drawable.ic_sleep_4
   5 -> R.drawable.ic_sleep_5
   else -> R.drawable.ic_sleep_active
})
  1. यहां अपडेट किया गया onBindViewHolder() फ़ंक्शन दिया गया है. यह ViewHolder के लिए सभी डेटा सेट करता है:
   override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val item = data[position]
        val res = holder.itemView.context.resources
        holder.sleepLength.text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, res)
        holder.quality.text= convertNumericQualityToString(item.sleepQuality, res)
        holder.qualityImage.setImageResource(when (item.sleepQuality) {
            0 -> R.drawable.ic_sleep_0
            1 -> R.drawable.ic_sleep_1
            2 -> R.drawable.ic_sleep_2
            3 -> R.drawable.ic_sleep_3
            4 -> R.drawable.ic_sleep_4
            5 -> R.drawable.ic_sleep_5
            else -> R.drawable.ic_sleep_active
        })
    }
  1. अपने ऐप्लिकेशन को चलाएं. आपकी स्क्रीन पर, नीचे दिए गए स्क्रीनशॉट की तरह दिखना चाहिए. इसमें नींद की क्वालिटी का आइकॉन, नींद में बिताए गए समय, और नींद की क्वालिटी के बारे में जानकारी देने वाला टेक्स्ट दिखना चाहिए.

आपका RecyclerView अब पूरा हो गया है! आपने Adapter और ViewHolder को लागू करने का तरीका सीखा. साथ ही, आपने RecyclerView Adapter के साथ सूची दिखाने के लिए, इन दोनों को एक साथ इस्तेमाल किया.

अब तक के कोड में, अडैप्टर और व्यू होल्डर बनाने की प्रोसेस दिखाई गई है. हालांकि, इस कोड को बेहतर बनाया जा सकता है. डेटा दिखाने और व्यू होल्डर मैनेज करने का कोड मिक्स हो गया है. साथ ही, onBindViewHolder() को ViewHolder अपडेट करने के तरीके के बारे में जानकारी है.

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

पहला चरण: onBindViewHolder() को फिर से फ़ैक्टर करना

इस चरण में, कोड को फिर से व्यवस्थित किया जाता है और व्यू होल्डर की सभी सुविधाओं को ViewHolder में ले जाया जाता है. इस रिफ़ैक्टरिंग का मकसद, ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) में बदलाव करना नहीं है. इसका मकसद, डेवलपर के लिए कोड पर काम करना आसान और सुरक्षित बनाना है. अच्छी बात यह है कि Android Studio में आपकी मदद करने के लिए टूल उपलब्ध हैं.

  1. SleepNightAdapter में, onBindViewHolder() में, वैरिएबल item को डिक्लेयर करने के लिए स्टेटमेंट को छोड़कर बाकी सब कुछ चुनें.
  2. राइट क्लिक करें. इसके बाद, रीफ़ैक्टर > एक्सट्रैक्ट > फ़ंक्शन चुनें.
  3. फ़ंक्शन का नाम bind रखें और सुझाए गए पैरामीटर स्वीकार करें. ठीक है पर क्लिक करें.

    bind() फ़ंक्शन को onBindViewHolder() के नीचे रखा गया है.
    private fun bind(holder: ViewHolder, item: SleepNight) {
        val res = holder.itemView.context.resources
        holder.sleepLength.text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, res)
        holder.quality.text = convertNumericQualityToString(item.sleepQuality, res)
        holder.qualityImage.setImageResource(when (item.sleepQuality) {
            0 -> R.drawable.ic_sleep_0
            1 -> R.drawable.ic_sleep_1
            2 -> R.drawable.ic_sleep_2
            3 -> R.drawable.ic_sleep_3
            4 -> R.drawable.ic_sleep_4
            5 -> R.drawable.ic_sleep_5
            else -> R.drawable.ic_sleep_active
        })
    }
  1. कर्सर को bind() के holder पैरामीटर के holder शब्द पर रखें. इंटेंशन मेन्यू खोलने के लिए, Alt+Enter (Mac पर Option+Enter) दबाएं. इसे ऐसे एक्सटेंशन फ़ंक्शन में बदलने के लिए, पैरामीटर को रिसीवर में बदलें को चुनें जिसका सिग्नेचर यह है:
private fun ViewHolder.bind(item: SleepNight) {...}
  1. bind() फ़ंक्शन को काटकर, ViewHolder में चिपकाएं.
  2. bind() को सार्वजनिक करें.
  3. अगर ज़रूरी हो, तो अडैप्टर में bind() इंपोर्ट करें.
  4. अब यह ViewHolder में है. इसलिए, हस्ताक्षर से ViewHolder वाला हिस्सा हटाया जा सकता है. यहां ViewHolder क्लास में bind() फ़ंक्शन का फ़ाइनल कोड दिया गया है.
fun bind(item: SleepNight) {
   val res = itemView.context.resources
   sleepLength.text = convertDurationToFormatted(
           item.startTimeMilli, item.endTimeMilli, res)
   quality.text = convertNumericQualityToString(
           item.sleepQuality, res)
   qualityImage.setImageResource(when (item.sleepQuality) {
       0 -> R.drawable.ic_sleep_0
       1 -> R.drawable.ic_sleep_1
       2 -> R.drawable.ic_sleep_2
       3 -> R.drawable.ic_sleep_3
       4 -> R.drawable.ic_sleep_4
       5 -> R.drawable.ic_sleep_5
       else -> R.drawable.ic_sleep_active
   })
}

दूसरा चरण: onCreateViewHolder को फिर से फ़ैक्टर करना

फ़िलहाल, अडैप्टर में मौजूद onCreateViewHolder() तरीके से, ViewHolder के लिए लेआउट रिसॉर्स से व्यू को बड़ा किया जाता है. हालांकि, महंगाई का अडैप्टर से कोई लेना-देना नहीं है. इसका पूरा असर ViewHolder पर पड़ता है. महंगाई ViewHolder में होनी चाहिए.

  1. onCreateViewHolder() में, फ़ंक्शन के मुख्य हिस्से में मौजूद सभी कोड चुनें.
  2. राइट क्लिक करें. इसके बाद, रीफ़ैक्टर > एक्सट्रैक्ट > फ़ंक्शन चुनें.
  3. फ़ंक्शन का नाम from रखें और सुझाए गए पैरामीटर स्वीकार करें. ठीक है पर क्लिक करें.
  4. कर्सर को फ़ंक्शन के नाम from पर रखें. इंटेंशन मेन्यू खोलने के लिए, Alt+Enter (Mac पर Option+Enter) दबाएं.
  5. साथ में मौजूद ऑब्जेक्ट में ले जाएं को चुनें. from() फ़ंक्शन को कंपैनियन ऑब्जेक्ट में होना चाहिए, ताकि इसे ViewHolder क्लास पर कॉल किया जा सके. इसे ViewHolder इंस्टेंस पर कॉल नहीं किया जाना चाहिए.
  6. companion ऑब्जेक्ट को ViewHolder क्लास में ले जाएं.
  7. from() को सार्वजनिक करें.
  8. onCreateViewHolder() में, return स्टेटमेंट को बदलकर, ViewHolder क्लास में from() को कॉल करने का नतीजा दिखाएं.

    पूरे किए गए onCreateViewHolder() और from() तरीके, नीचे दिए गए कोड की तरह दिखने चाहिए. साथ ही, आपका कोड बिना किसी गड़बड़ी के काम करना चाहिए.
    override fun onCreateViewHolder(parent: ViewGroup, viewType: 
Int): ViewHolder {
        return ViewHolder.from(parent)
    }
companion object {
   fun from(parent: ViewGroup): ViewHolder {
       val layoutInflater = LayoutInflater.from(parent.context)
       val view = layoutInflater
               .inflate(R.layout.list_item_sleep_night, parent, false)
       return ViewHolder(view)
   }
}
  1. ViewHolder क्लास के सिग्नेचर को बदलें, ताकि कंस्ट्रक्टर निजी हो. from() अब एक ऐसा तरीका है जो नया ViewHolder इंस्टेंस दिखाता है. इसलिए, अब किसी को भी ViewHolder के कंस्ट्रक्टर को कॉल करने की ज़रूरत नहीं है.
class ViewHolder private constructor(itemView: View) : RecyclerView.ViewHolder(itemView){
  1. ऐप्लिकेशन चलाएं. आपका ऐप्लिकेशन पहले की तरह ही बनना और चलना चाहिए. रिफ़ैक्टरिंग के बाद, यही नतीजा मिलना चाहिए.

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

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

अपने डेटा को RecyclerView में दिखाने के लिए, आपको इन चीज़ों की ज़रूरत होगी:

  • RecyclerView
    RecyclerView का इंस्टेंस बनाने के लिए, लेआउट फ़ाइल में <RecyclerView> एलिमेंट को तय करें.
  • LayoutManager
    RecyclerView में मौजूद आइटम के लेआउट को व्यवस्थित करने के लिए, LayoutManager का इस्तेमाल करता है. जैसे, उन्हें ग्रिड या लीनियर लिस्ट में व्यवस्थित करना.

    लेआउट फ़ाइल में मौजूद <RecyclerView> में, app:layoutManager एट्रिब्यूट को लेआउट मैनेजर (जैसे, LinearLayoutManager या GridLayoutManager) पर सेट करें.

    RecyclerView के लिए, LayoutManager को प्रोग्राम के हिसाब से भी सेट किया जा सकता है.RecyclerView (इस तकनीक के बारे में, बाद के कोडलैब में बताया गया है.)
  • हर आइटम के लिए लेआउट
    एक्सएमएल लेआउट फ़ाइल में, डेटा के एक आइटम के लिए लेआउट बनाएं.
  • अडैप्टर
    ऐसा अडैप्टर बनाएं जो डेटा तैयार करे और यह तय करे कि उसे ViewHolder में कैसे दिखाया जाएगा. अडैप्टर को RecyclerView से जोड़ें.

    जब RecyclerView चलता है, तब यह अडैप्टर का इस्तेमाल करके यह पता लगाता है कि स्क्रीन पर डेटा कैसे दिखाया जाए.

    अडैप्टर के लिए, आपको इन तरीकों को लागू करना होगा:
    getItemCount(), ताकि आइटम की संख्या दिखाई जा सके.
    onCreateViewHolder(), ताकि सूची में मौजूद किसी आइटम के लिए ViewHolder दिखाया जा सके.
    onBindViewHolder(), ताकि सूची में मौजूद किसी आइटम के लिए डेटा को व्यू के हिसाब से अडैप्ट किया जा सके.

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

Udacity का कोर्स:

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

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

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

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

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

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

पहला सवाल

RecyclerView, आइटम कैसे दिखाता है? लागू होने वाले सभी विकल्पों को चुनें.

▢ आइटम को सूची या ग्रिड में दिखाता है.

▢ ऊपर-नीचे या दाएं-बाएं स्क्रोल करता है.

▢ टैबलेट जैसे बड़े डिवाइसों पर, यह तिरछे स्क्रोल होता है.

▢ जब इस्तेमाल के उदाहरण के लिए सूची या ग्रिड काफ़ी नहीं होता है, तब कस्टम लेआउट की अनुमति देता है.

दूसरा सवाल

RecyclerView का इस्तेमाल करने के क्या फ़ायदे हैं? लागू होने वाले सभी विकल्पों को चुनें.

▢ बड़ी सूचियों को आसानी से दिखाता है.

▢ डेटा अपने-आप अपडेट होता है.

▢ किसी आइटम को अपडेट करने, मिटाने या सूची में जोड़ने पर, पेज को रीफ़्रेश करने की ज़रूरत कम होती है.

▢ यह व्यू का फिर से इस्तेमाल करता है. इससे स्क्रीन पर स्क्रोल होने वाला अगला आइटम दिखता है.

तीसरा सवाल

अडैप्टर का इस्तेमाल करने की कुछ वजहें क्या हैं? लागू होने वाले सभी विकल्पों को चुनें.

▢ कोड को अलग-अलग हिस्सों में बांटने से, कोड में बदलाव करना और उसकी जांच करना आसान हो जाता है.

RecyclerView को दिखाए जा रहे डेटा से कोई फ़र्क़ नहीं पड़ता.

▢ डेटा प्रोसेसिंग लेयर को इस बात से कोई मतलब नहीं होता कि डेटा कैसे दिखाया जाएगा.

▢ ऐप्लिकेशन तेज़ी से चलेगा.

चौथा सवाल

ViewHolder के बारे में इनमें से कौनसी बातें सही हैं? लागू होने वाले सभी विकल्पों को चुनें.

ViewHolder लेआउट को एक्सएमएल लेआउट फ़ाइलों में तय किया जाता है.

▢ डेटासेट में मौजूद डेटा की हर यूनिट के लिए, एक ViewHolder होता है.

▢ किसी RecyclerView में एक से ज़्यादा ViewHolder हो सकते हैं.

Adapter, डेटा को ViewHolder से बाइंड करता है.

अगला सबक शुरू करें: 7.2: RecyclerView के साथ DiffUtil और डेटा बाइंडिंग