Android रीसाइक्लरव्यू: क्या है, सरल उदाहरणों से जानें

⚡ स्मार्ट सारांश

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

  • ???? यह क्या है: RecyclerView, ListView और GridView का एक लचीला उत्तराधिकारी है जिसका उपयोग बड़े डेटा संग्रहों को प्रदर्शित करने के लिए किया जाता है।
  • 🧱 व्यू और व्यूग्रुप: Android यह इंटरफ़ेस को View और ViewGroup क्लास का उपयोग करके बनाता है, जिसमें LayoutParams आकार और स्थिति को नियंत्रित करते हैं।
  • 🔄 एडाप्टर: एडाप्टर पैटर्न डेटा ऐरे को व्यूहोल्डर्स में परिवर्तित करता है जिन्हें रीसायक्लरव्यू स्वीकार कर सकता है।
  • 📐 लेआउट प्रबंधक: लेआउट मैनेजर आइटमों को रैखिक रूप से या ग्रिड में व्यवस्थित करता है और यह संकेत देता है कि दृश्यों को कब पुनः उपयोग किया जा सकता है।
  • ♻️ पुनर्चक्रण: स्क्रीन से बाहर के दृश्यों को दोबारा बनाने के बजाय उनका पुनः उपयोग किया जाता है, जिससे मेमोरी की बचत होती है और स्क्रॉलिंग सुचारू रूप से चलती रहती है।
  • कदम बनाएँ: जोड़ें Gradle निर्भरता के आधार पर, एक आइटम लेआउट, एक व्यूहोल्डर, एक एडेप्टर और एक लेआउट मैनेजर बनाएं।

Android पुनर्चक्रण दृश्य

RecyclerView क्या है? Android?

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

दृश्य

RSI Android प्लेटफॉर्म स्क्रीन पर आइटम प्रदर्शित करने के लिए View और ViewGroup क्लास का उपयोग करता है। ये क्लास एब्सोल्यूट हैं।tract और t को उपयोग के अनुसार अलग-अलग कार्यान्वयनों में विस्तारित किया जाता है। उदाहरण के लिए, TextView का सरल उद्देश्य स्क्रीन पर पाठ सामग्री प्रदर्शित करना है। EditText इसी View क्लास से विस्तारित होता है और उपयोगकर्ता को डेटा इनपुट करने में सक्षम बनाने के लिए अतिरिक्त कार्यक्षमता जोड़ता है।

विकास के दौरान अधिक लचीलापन प्राप्त करने के लिए हम अपने स्वयं के कस्टम व्यू बना सकते हैं।ping उपयोगकर्ता इंटरफेस। व्यू क्लास ऐसे तरीके प्रदान करती है जिन्हें हम स्क्रीन पर चित्र बनाने के लिए ओवरराइड कर सकते हैं और चौड़ाई, ऊंचाई और हमारे स्वयं के कस्टम एट्रिब्यूट जैसे पैरामीटर पास करने का साधन प्रदान करती है जिन्हें हम अपने व्यू में जोड़ना चाहते हैं ताकि यह हमारी इच्छानुसार व्यवहार करे।

समूह देखें

ViewGroup क्लास एक प्रकार का View है, लेकिन साधारण View क्लास के विपरीत, जिसका काम केवल डिस्प्ले करना होता है, ViewGroup हमें एक ही View में कई Views को जोड़ने की सुविधा देता है, जिसे हम समग्र रूप से संदर्भित कर सकते हैं। इस मामले में, शीर्ष स्तर पर बनाया गया View जिसमें हम अन्य साधारण Views जोड़ते हैं, उसे "पैरेंट" कहा जाता है, और इसके अंदर जोड़े गए Views को "चिल्ड्रन" कहा जाता है।

हम व्यू को एक ऐरे और व्यूग्रुप को ऐरे ऑफ ऐरे के रूप में कल्पना कर सकते हैं। चूंकि ऐरे ऑफ ऐरे स्वयं एक ऐरे होता है, इसलिए हम देख सकते हैं कि व्यूग्रुप को व्यू की तरह कैसे माना जा सकता है।

var arr1 = [1,2,3] //imagine a simple View as an Array
//we can imagine this as a NumberTextView which doesn't really exist
//but we could imagine there's one that makes it easy to use numbers
var arr2 = ["a","b","c"] // We can imagine this as another simple view

var nestedArr = [arr1,arr2] //in our analogy, we can now group views
//together and the structure that would hold that would be what we call the ViewGroup

ViewGroup हमें यह परिभाषित करने की सुविधा भी देता है कि व्यू के भीतर चाइल्ड ऑब्जेक्ट्स को कैसे व्यवस्थित किया जाए, उदाहरण के लिए, उन्हें लंबवत या क्षैतिज रूप से व्यवस्थित किया जाए। व्यू के भीतर परस्पर क्रिया के लिए हम अलग-अलग नियम बना सकते हैं। उदाहरण के लिए, एक दूसरे के बाद आने वाले TextViews के बीच 12 दशमलव स्थानों की दूरी होनी चाहिए, जबकि एक ImageView के बाद आने वाले TextView के बीच 5 दशमलव स्थानों की दूरी होनी चाहिए।

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

RSI Android दस्तावेज़ीकरण यह कुछ डिफ़ॉल्ट पैरामीटर प्रदान करता है जिन्हें हम अपने व्यूग्रुप को कॉन्फ़िगर करते समय लागू करेंगे। कुछ सामान्य पैरामीटर चौड़ाई, ऊँचाई और मार्जिन से संबंधित हैं। डिफ़ॉल्ट रूप से, इन कॉन्फ़िगरेशन की संरचना ऊँचाई के लिए android:layout_height और चौड़ाई के लिए android:layout_width होती है। इस संबंध में, जब आप अपना व्यूग्रुप बनाते हैं, तो आप अपने व्यूग्रुप के व्यवहार के अनुसार विशिष्ट लेआउट पैरामीटर बना सकते हैं।

Android इसमें डिफ़ॉल्ट व्यू और व्यूग्रुप शामिल हैं जिनका उपयोग हम कई सामान्य कार्यों को करने के लिए कर सकते हैं। उदाहरण के लिए, हमने टेक्स्ट व्यू का उल्लेख किया है। यह एक सरल व्यू है जिसमें ऊंचाई, चौड़ाई और टेक्स्ट साइज़ जैसे कॉन्फ़िगर करने योग्य पहलू होते हैं। इसके अलावा, हमारे पास इमेज प्रदर्शित करने के लिए इमेज व्यू और एडिट टेक्स्ट भी हैं, जैसा कि हमने पहले बताया था। Android इसमें कस्टम व्यूग्रुप्स भी हैं, जिनमें हम अपने व्यूज जोड़ सकते हैं और अपेक्षित व्यवहार प्राप्त कर सकते हैं।

लीनियर लयआउट

LinearLayout हमें इसमें View आइटम जोड़ने की अनुमति देता है। LinearLayout में एक orientation विशेषता होती है जो यह निर्धारित करती है कि इसे स्क्रीन पर कैसे व्यवस्थित किया जाएगा। इसमें LinearLayout.LayoutParams भी होते हैं जो इसके अंदर मौजूद Views के लिए नियम निर्धारित करते हैं। उदाहरण के लिए, android:center_horizontal विशेषता Views को क्षैतिज अक्ष के साथ केंद्र में रखती है, जबकि android:center_vertical विशेषता View की सामग्री को ऊर्ध्वाधर अक्ष के साथ केंद्र में रखती है।

सेंटरिंग को समझने में मदद के लिए यहां कुछ चित्र दिए गए हैं। मान लीजिए यह 200px x 200px के स्पेस में एक साधारण TextView है; सेंटरिंग एट्रिब्यूट के अनुसार यह इस प्रकार व्यवहार करेगा।

android:center_horizontal

क्षैतिज रूप से केंद्रित सामग्री

क्षैतिज रूप से केंद्रित सामग्री

एंड्रॉइड: सेंटर_वर्टिकल

ऊर्ध्वाधर रूप से केंद्रित सामग्री

ऊर्ध्वाधर रूप से केंद्रित सामग्री

एंड्रॉयड:केंद्र

केंद्रित सामग्री

केंद्रित सामग्री

रीसाइक्लर व्यू के मुख्य घटक

रीसाइक्लर व्यू के मुख्य घटक

रीसाइक्लर व्यू के मुख्य घटक

रीसाइक्लरव्यू के महत्वपूर्ण घटक निम्नलिखित हैं:

रीसाइक्लर व्यू.एडाप्टर

ग्राउंडवर्क #1 – एडाप्टर पैटर्न

एडाप्टर एक ऐसा उपकरण है जो एक सिस्टम या डिवाइस के गुणों को किसी असंगत डिवाइस या सिस्टम के गुणों में परिवर्तित करता है। कुछ एडाप्टर सिग्नल या पावर गुणों को संशोधित करते हैं, जबकि अन्य केवल एक कनेक्टर के भौतिक स्वरूप को दूसरे कनेक्टर के अनुरूप ढालते हैं।

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

प्रोग्रामिंग में यही स्थिति तब उत्पन्न होती है जब हम किसी कार्य को पूरा करने के लिए दो डेटा संरचनाओं को आपस में जोड़ना चाहते हैं, लेकिन उनके डिफ़ॉल्ट पोर्ट में एक दूसरे के साथ संवाद करने का कोई तरीका नहीं होता है।

हम एक डिवाइस और चार्जर का सरल उदाहरण लेंगे। हमारे पास चार्जर के दो उदाहरण होंगे, एक अमेरिकी और एक ब्रिटिश।

class AmericanCharger() {
    var chargingPower = 10
}
class BritishCharger(){
    var chargingPower = 5
}

फिर हम दो उपकरण बनाएंगे।

class AmericanDevice()
class BritishDevice()

उदाहरण के तौर पर, हम खेलने के लिए उपकरणों के कुछ उदाहरण बना सकते हैं।

var myAmericanPhone = new AmericanDevice()
var myBritishPhone = new BritishDevice()

इसके बाद हम दोनों उपकरणों में charge() नामक एक विधि जोड़कर चार्जिंग की अवधारणा को प्रस्तुत करेंगे। यह विधि संबंधित चार्जर को इनपुट के रूप में लेती है और उसके आधार पर चार्जिंग करती है।

sealed trait Device
class AmericanDevice : Device{
    fun charge(charger:AmericanCharger){
        //Do some American charging
    }
}
class BritishDevice: Device{
    fun charge(charger:BritishCharger){
        //Do some British charging
    }
}

इस मामले में, हमारे उदाहरण के आधार पर, हमें किसी न किसी कारण से अमेरिकी डिवाइस का उपयोग करते समय ब्रिटिश चार्जर का उपयोग करने की आवश्यकता होगी, या इसके विपरीत।

प्रोग्रामिंग की दुनिया में, ऐसा आमतौर पर तब होता है जब लाइब्रेरीज़ को एक साथ मिलाया जाता है जो समान कार्यक्षमता प्रदान करती हैं (हमारे संदर्भ में, हमारी साझा कार्यक्षमता चार्ज कर रही है)। हमें इसे सक्षम करने का एक तरीका खोजने की आवश्यकता होगी।

अगर हम इस उदाहरण का अनुसरण करें, तो हमें एक इलेक्ट्रॉनिक्स दुकान पर जाकर एक ऐसा एडाप्टर खरीदना होगा जो हमें ब्रिटिश चार्जर का उपयोग करके अमेरिकी उपकरणों को चार्ज करने में सक्षम बनाए। प्रोग्रामिंग के दृष्टिकोण से, हम एडाप्टर के निर्माता होंगे।

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

class AmericanToBritishChargerAdapter(theAmericanCharger:AmericanCharger){
    fun returnNewCharger(): BritishCharger{
            //convert the American charger to a BritishCharger
            //we would change the American charging functionality
            //to British charging functionality to make sure the
            //adapter doesn't destroy the device. The adapter could
            //, for example, control the power output by dividing by 2
            //our adapter could encompass this functionality in here

           var chargingPower:Int = theAmericanCharger.chargingPower / 2
           var newBritishCharger = new BritishCharger()
           newBritishCharger.chargingPower = theAmericanCharger.chargingPower/2

        return newBritishCharger
    }
}

प्रोग्रामिंग की दुनिया में, सॉकेट में अंतर चार्जिंग के लिए उपयोग की जाने वाली विधियों में अंतर के समान है। अलग-अलग चार्जिंग विधियों वाले चार्जर का उपयोग करना असंभव हो जाएगा।

var myBritishDevice = new BritishDevice()
var americanChargerIFound = new AmericanCharger()

myBritishDevice पर americanChargerIFound के साथ charge() मेथड को कॉल करने का प्रयास काम नहीं करेगा, क्योंकि AmericanDevice केवल AmericanCharger को ही स्वीकार करता है। इसलिए ऐसा करना असंभव है:

var myBritishDevice = new BritishDevice()
var americanChargerIFound = new AmericanCharger()
myBritishDevice.charge(americanChargerIFound)

इस स्थिति में, हमने जो एडेप्टर बनाया है, AmericanToBritishChargerAdapter, वह अब काम आ सकता है। हम returnNewCharger() मेथड का उपयोग करके एक नया BritishCharger बना सकते हैं, जिसका उपयोग हम चार्ज करने के लिए कर सकते हैं। हमें बस अपने एडेप्टर का एक इंस्टेंस बनाना है और उसमें हमारे पास मौजूद AmericanCharger डालना है, और यह एक BritishCharger बना देगा जिसका हम उपयोग कर सकते हैं।

var myBritishDevice = new BritishDevice()
var americanChargerIFound = new AmericanCharger()
//We create the adapter and feed it the americanCharger
var myAdapter =  AmericanToBritishChargerAdapter(americanChargerIFound)
//calling returnNewCharger from myAdapter would return a BritishCharger
var britishChargerFromAdapter = myAdapter.returnNewCharger()
//and once we have the britishCharger we can now use it
myBritishDevice.charge(britishChargerFromAdapter)

रीसाइक्लर व्यू.लेआउट मैनेजर

ViewGroup के साथ काम करते समय, इसके अंदर Views स्थित होते हैं। LayoutManager का काम Views को उसके अंदर व्यवस्थित करने का तरीका बताना है।

तुलना के लिए, जब हम LinearLayout ViewGroup के साथ काम करते हैं, तो हमारी ज़रूरत यह होती है कि हम आइटम को लंबवत या क्षैतिज रूप से रख सकें। इसे एक ओरिएंटेशन एट्रिब्यूट जोड़कर आसानी से लागू किया जा सकता है, जो हमें बताता है कि LinearLayout स्क्रीन पर कैसे रखा जाएगा। हम इसे निम्न प्रकार से कर सकते हैं: android:orientation=VERTICAL|HORIZONTAL विशेषता।

हमारे पास ग्रिडलेआउट नामक एक और व्यूग्रुप है। इसका उपयोग तब किया जाता है जब हम व्यूज़ को आयताकार ग्रिड संरचना में व्यवस्थित करना चाहते हैं। इसका कारण ऐप उपयोगकर्ता को प्रस्तुत किए जाने वाले डेटा को आसानी से समझने योग्य बनाना हो सकता है। ग्रिडलेआउट की डिज़ाइन ऐसी है कि इसमें ग्रिड के आयामों को परिभाषित करके इस लक्ष्य को प्राप्त करने में सहायता के लिए कॉन्फ़िगरेशन की सुविधा उपलब्ध है; उदाहरण के लिए, हम 4×4 ग्रिड या 3×2 ग्रिड बना सकते हैं।

रीसाइक्लर व्यू.व्यूहोल्डर

व्यूहोल्डर एक एब्स हैtract क्लास जिसे हम RecyclerView से भी विस्तारित करते हैं। ViewHolder हमें सामान्य विधियाँ प्रदान करता है जो हमें RecyclerView पर रखे गए View को संदर्भित करने में मदद करती हैं, भले ही RecyclerView में रीसाइक्लिंग प्रक्रिया ने उन विभिन्न संदर्भों को बदल दिया हो जिनके बारे में हमें जानकारी नहीं है।

बड़ी सूचियाँ

RecyclerViews का उपयोग तब किया जाता है जब हम उपयोगकर्ता को Views का एक बहुत बड़ा सेट प्रस्तुत करना चाहते हैं, और साथ ही साथ मेमोरी को भी पूरी तरह से उपयोग में नहीं लाना चाहते। रैम हमारे डिवाइस पर निर्मित दृश्य के प्रत्येक उदाहरण के लिए।

संपर्क सूची का उदाहरण लें तो, हमें इस बात का सामान्य अंदाजा होगा कि सूची में एक संपर्क कैसा दिखेगा। फिर हम एक टेम्पलेट लेआउट बनाएंगे, जो वास्तव में एक व्यू होता है, जिसमें स्लॉट होंगे जहां हमारी संपर्क सूची से विभिन्न डेटा भरा जाएगा। नीचे दिया गया स्यूडो कोड इस पूरी प्रक्रिया को समझाता है:

//OneContactView
<OneContact>
<TextView>{{PlaceHolderForName}}</TextView>
<TextView>{{PlaceHolderForAddress}}</TextView>
<ImageView>{{PlaceHolderForProfilePicture}}</ImageView>
<TextView>{{PlaceHolderForPhoneNumber}}</TextView>
</OneContact>

तब हमारे पास इस प्रकार की संपर्क सूची होगी:

<ContactList>
</ContactList>

यदि हम सामग्री को हार्डकोड करते, तो ऐप को दोबारा लिखे बिना सूची में नई सामग्री जोड़ने का कोई प्रोग्रामेटिक तरीका नहीं होता। सौभाग्य से, व्यूग्रुप में व्यू जोड़ना समर्थित है। addView(view:View) फिर भी, यह वह तरीका नहीं है जिससे RecyclerView में चाइल्ड व्यू जोड़े जाते हैं।

हमारे उपयोग के उदाहरण में, हमारे पास संपर्कों की एक लंबी सूची होगी। सूची में प्रत्येक संपर्क के लिए, हमें एक OneContactView बनाना होगा और View के अंदर Contact क्लास के फ़ील्ड से मेल खाने वाला डेटा भरना होगा। फिर, View तैयार हो जाने पर, सूची दिखाने के लिए हमें इसे RecyclerView में जोड़ना होगा।

data  class Contact(var name:String, var address:String, var pic:String, var phoneNumber:Int)

var contact1 = Contact("Guru","Guru97", "SomePic1.jpg", 991)
var contact2 = Contact("Guru","Guru98", "SomePic2.jpg", 992)
var contact3 = Contact("Guru","Guru99", "SomePic3.jpg", 993)

var myContacts:ArrayList<Contact> = arrayListOf<Contact>(contact1,contact2,contact3)

हमारे पास कॉन्टैक्ट्स का एक ऐरे है। OneContactView में कॉन्टैक्ट क्लास से कंटेंट लेने और उसे डिस्प्ले करने के लिए स्लॉट्स हैं। RecyclerView में, हमें Views जोड़ने होंगे ताकि यह रीसाइक्लिंग क्षमता में हमारी मदद कर सके।

RecyclerView हमें सीधे व्यू जोड़ने की अनुमति नहीं देता है, लेकिन ViewHolder जोड़ने की सुविधा देता है। इसलिए, इस स्थिति में, हमारे पास दो हिस्से हैं जिन्हें हम जोड़ना चाहते हैं, लेकिन वे मेल नहीं खाते। यहीं पर हमारा एडाप्टर काम आता है। RecyclerView हमें एक एडाप्टर प्रदान करता है, ठीक उसी तरह जैसे हमारा AmericanToBritishChargerAdapter() पहले मिली जानकारी के आधार पर हम अपने अमेरिकी चार्जर को, जो हमारे ब्रिटिश डिवाइस के साथ इस्तेमाल करने लायक नहीं था, एक उपयोगी चीज में बदल पाए, जो वास्तविक जीवन में पावर एडॉप्टर की तरह काम करता है।

इस परिदृश्य में, एडेप्टर हमारे संपर्कों की सरणी और हमारे व्यू को लेगा, और वहां से व्यूहोल्डर्स उत्पन्न करेगा जिन्हें रीसायक्लरव्यू स्वीकार करने के लिए तैयार है।

RecyclerView एक इंटरफ़ेस प्रदान करता है जिसे हम RecyclerView.Adapter क्लास के माध्यम से विस्तारित करके अपना एडॉप्टर बना सकते हैं। इस एडॉप्टर के अंदर ViewHolder क्लास बनाने का तरीका है जिसके साथ RecyclerView काम करना चाहता है। तो, हमारे पास पहले जैसी ही स्थिति है, लेकिन एक अतिरिक्त चीज़ के साथ, यानी एडॉप्टर।

हमारे पास कॉन्टैक्ट्स का एक ऐरे है, एक कॉन्टैक्ट को डिस्प्ले करने के लिए एक व्यू (OneContactView), और एक RecyclerView है, जो व्यूज़ की एक लिस्ट है और रीसाइक्लिंग सेवाएं प्रदान करती है, लेकिन केवल ViewHolders को ही स्वीकार करती है। इस स्थिति में, हमारे पास अब एक RecyclerView.Adapter क्लास है, जिसमें ViewHolders बनाने के लिए एक मेथड है।

fun createViewHolder(@NonNull parent: ViewGroup, viewType: Int): ViewHolder

RecyclerView.ViewHolder एक एब्स हैtracयह एक क्लास है जो हमारे व्यू को एक आर्गुमेंट के रूप में लेती है और उसे व्यूहोल्डर में परिवर्तित करती है। यह रैपर पैटर्न का उपयोग करती है, जिसका उपयोग क्लास की क्षमताओं को बढ़ाने के लिए किया जाता है।

ग्राउंडवर्क #2 – रैपर पैटर्न

हम एक सरल उदाहरण का उपयोग करके यह दिखाएंगे कि हम जानवरों को कैसे बुलवा सकते हैं।

sealed trait Animal{
    fun sound():String
}

data class Cat(name:String):Animal{
    fun sound(){
        "Meow"
        }
}
data class Dog(name:String):Animal{
    fun sound(){
        "Woof"
        }
}

var cat1 = Cat("Tubby")
var dog1 = Dog("Scooby")
cat1.sound() //meow
dog1.sound() //woof

ऊपर दिए गए उदाहरण में, हमारे पास दो जानवर हैं। मान लीजिए कि हम उनमें बोलने की क्षमता जोड़ने का कोई तरीका चाहते हैं, लेकिन लाइब्रेरी के लेखक का रवैया अच्छा नहीं है, तो भी हम इसका उपाय ढूंढ सकते हैं। इसके लिए हमें अपनी एनिमल क्लास के लिए एक रैपर की आवश्यकता होगी। हम एनिमल क्लास को अपनी क्लास के कंस्ट्रक्टर के रूप में लेकर ऐसा कर सकते हैं।

class SpeechPoweredAnimalByWrapper(var myAnimal:Animal){

    fun sound(){
        myAnimal.sound()
    }

    fun speak(){
        println("Hello, my name is ${myAnimal.name}")
    }
}

अब हम SpeechPoweredAnimalByWrapper में एक एनिमल इंस्टेंस पास कर सकते हैं। इस पर sound() मेथड को कॉल करने से पास किए गए एनिमल का sound() मेथड कॉल होगा। हमारे पास एक अतिरिक्त speak() मेथड भी है, जो पास किए गए एनिमल्स में जोड़ी गई नई कार्यक्षमता के रूप में काम करता है। हम इसका उपयोग इस प्रकार कर सकते हैं:

var cat1 =  Cat("Garfield")
cat1.sound()//"meow"
cat1.speak()// doesn't work as it isn't implemented
var talkingCat = new SpeechPoweredAnimalByWrapper(cat1)
talkingCat.sound() //"meow" the sound method calls the one defined for cat1
talkingCat.speak() //"Hello, my name is Garfield"

इस पैटर्न का उपयोग करके, हम क्लास ले सकते हैं और उसमें कार्यक्षमता जोड़ सकते हैं। हमें बस एक क्लास इंस्टेंस और हमारे रैप द्वारा परिभाषित नए मेथड पास करने की आवश्यकता है।ping वर्ग.

ऊपर दिए गए उदाहरण में, हमने एक कंक्रीट क्लास का उपयोग किया है। इसे एक एब्सोल्यूट क्लास में भी लागू किया जा सकता है।tract क्लास। हमें SpeechPoweredAnimalByWrapper क्लास को abs में बदलना होगा।tracऔर बस, काम पूरा हो गया। हम क्लास का नाम बदलकर छोटा कर देंगे ताकि यह पढ़ने में आसान हो जाए।

abstract class SpeechPowered(var myAnimal:Animal){

    fun sound(){
        myAnimal.sound()
    }

    fun speak(){
        println("Hello, my name is ${myAnimal.name}")
    }
}

यह पहले जैसा ही है, लेकिन इसका मतलब कुछ और होगा। एक सामान्य क्लास में, हम उसी तरह से क्लास का इंस्टेंस बना सकते हैं जैसे हमने cat1 और dog1 बनाए थे।tracहालाँकि, t क्लास को इंस्टैंशिएट करने के लिए नहीं बनाया गया है, बल्कि इनका उद्देश्य अन्य क्लासों को एक्सटेंड करना है। तो हम new SpeechPowered(var myAnimal:Animal) abs का उपयोग कैसे करेंगे?tracक्या हम इसे टी क्लास के रूप में उपयोग कर सकते हैं? हम नई क्लास बनाकर इसका उपयोग कर सकते हैं जो इसे विस्तारित करेंगी और बदले में, इसकी कार्यक्षमता प्राप्त करेंगी।

हमारे उदाहरण में, हम SpeechPoweredAnimal नामक एक क्लास बनाएंगे जो इस क्लास को विस्तारित करती है।

class SpeechPoweredAnimal(var myAnimal:Animal):SpeechPowered(myAnimal)
var cat1 =  Cat("Tubby")
var speakingKitty = SpeechPoweredAnimal(cat1)
speakingKitty.speak() //"Hello, my name is Tubby"

ViewHolder में भी यही पैटर्न इस्तेमाल किया गया है। RecyclerView.ViewHolder क्लास एक एब्सोल्यूट ऑब्जेक्ट है।tracयह एक क्लास है जो व्यू में कार्यक्षमता जोड़ती है, ठीक वैसे ही जैसे हमने जानवरों में बोलने की विधि जोड़ी थी। यह अतिरिक्त कार्यक्षमता ही इसे रीसायक्लर व्यू के साथ काम करने योग्य बनाती है।

इस प्रकार हम OneContactView से OneContactViewHolder बनाएंगे:

//The View argument we pass is converted to a ViewHolder which uses the View to give it more abilities and in turn work with the RecyclerView
class OneContactViewHolder(ourContactView: View) : RecyclerView.ViewHolder(ourContactView)

RecyclerView में एक एडाप्टर होता है जो हमें अपने कॉन्टैक्ट्स एरे को RecyclerView के माध्यम से ContactsView से कनेक्ट करने की अनुमति देता है।

दृश्य जोड़ना

ViewGroup स्वचालित रूप से पुनः प्रदर्शित नहीं होता है, बल्कि एक निश्चित समय सारणी का पालन करता है। आपके डिवाइस पर यह हर 10 मिलीसेकंड या 100 मिलीसेकंड में पुनः प्रदर्शित हो सकता है; या, यदि हम कोई बेतुकी संख्या लें, जैसे कि 1 मिनट, तो जब हम किसी ViewGroup में कोई View जोड़ते हैं, तो ViewGroup के "रिफ्रेश" होने पर आपको 1 मिनट बाद परिवर्तन दिखाई देंगे।

रीसाइक्लरव्यू.रीसाइक्लर

आधारभूत कार्य #3 – कैशिंग

ब्राउज़र में नियमित रूप से पेज रिफ्रेश करने का एक बेहतरीन उदाहरण है। मान लीजिए, हम जिस वेबसाइट पर हैं वह स्थिर है और गतिशील रूप से सामग्री नहीं भेज रही है; ऐसे में बदलाव देखने के लिए हमें बार-बार पेज रिफ्रेश करना होगा।

इस उदाहरण के लिए, मान लीजिए कि हम ट्विटर साइट की बात कर रहे हैं। हमारे पास कई स्थिर ट्वीट सूचीबद्ध होंगे, और नए ट्वीट देखने का एकमात्र तरीका रिफ्रेश बटन पर क्लिक करके सामग्री को पुनः प्राप्त करना होगा।

पूरी स्क्रीन को फिर से पेंट करना जाहिर तौर पर एक महंगा काम है। कल्पना कीजिए कि अगर हमारे फोन प्रदाता के पास सीमित बैंडविड्थ हो और हमारी ट्वीट सूची में बहुत सारी छवियां और वीडियो हों; तो हर बार पेज को रिफ्रेश करने पर पेज की सारी सामग्री को फिर से डाउनलोड करना महंगा पड़ेगा।

हमें पहले से लोड किए गए ट्वीट्स को स्टोर करने का एक तरीका चाहिए और यह सुनिश्चित करना होगा कि हमारी अगली रिक्वेस्ट को पता हो कि उसके पास पहले से कौन-कौन से ट्वीट्स मौजूद हैं। इसलिए, यह सब कुछ दोबारा डाउनलोड नहीं करता है और केवल नए ट्वीट्स ही प्राप्त करता है, साथ ही यह भी जांचता है कि क्या स्थानीय रूप से सहेजा गया कोई ट्वीट अब मौजूद नहीं है ताकि उसे स्थानीय रूप से डिलीट किया जा सके। हम जिस प्रक्रिया का वर्णन कर रहे हैं उसे कैशिंग कहते हैं।

हम वेबसाइट को जो जानकारी भेजते हैं, उसे मेटा-डेटा कहते हैं। इसलिए, असल में हम सिर्फ यह नहीं कहते कि "हम आपकी साइट लोड करना चाहते हैं," बल्कि हम कहते हैं, "हम आपकी साइट लोड करना चाहते हैं, और पिछली बार लोड करते समय हमने कुछ सामग्री सहेज कर रखी थी; कृपया इसका उपयोग करके हमें केवल वही सामग्री भेजें जो पहले से मौजूद नहीं है, ताकि हम ज्यादा बैंडविड्थ का उपयोग न करें।"

लेआउट कॉल्स - ट्वीट सूची पागल होनी चाहिए

लेआउट कॉल का एक उदाहरण scrollToPosition है। यह चैटिंग ऐप्स जैसी चीज़ों में आम तौर पर देखने को मिलता है। अगर किसी चैट थ्रेड में कोई व्यक्ति पहले के चैट बबल का जवाब देता है, तो कुछ चैटिंग ऐप्स जवाब के साथ-साथ चैट बबल का लिंक भी दिखाते हैं, जिसे क्लिक करने पर आप उस जगह पहुँच जाते हैं जहाँ आपका मूल संदेश था।

यदि हम इस विधि को तब कॉल करते हैं जब हमने अपने RecyclerView में LayoutManager नहीं जोड़ा है और RecyclerView.Adapter भी नहीं जोड़ा है, तो scrollToPosition(n:Int) को अनदेखा कर दिया जाता है।

रीसाइक्लर व्यू घटकों के बीच संचार

आधारभूत कार्य #4 – कॉलबैक

अपने कार्य को करते समय, RecyclerView कई अलग-अलग कार्यों को संभालता है। इसे LayoutManager के साथ काम करना होता है, जो हमें बताता है कि Views को रैखिक रूप से या ग्रिड में कैसे व्यवस्थित करना है। इसे एक एडाप्टर के साथ भी काम करना होता है जो हमारे आइटम्स (contactList) को Views (OneContactView) में और फिर ViewHolders (OneContactViewHolder) में परिवर्तित करता है, जिनके साथ RecyclerView अपने द्वारा प्रदान किए गए तरीकों का उपयोग करके काम करने के लिए तैयार होता है।

RecyclerView के लिए कच्चा माल हमारे व्यूज़ हैं, जैसे कि OneContactView, और एक डेटा स्रोत।

contactList:Array<Contact>

हमने RecyclerView के उद्देश्य को समझने के लिए एक सरल उदाहरण का उपयोग किया है। उदाहरण के लिए, जब हमारे पास 1000 संपर्कों की एक स्थिर सूची होती है जिसे हम उपयोगकर्ता को दिखाना चाहते हैं, तो इसे समझना आसान है। लेकिन जब सूची स्थिर नहीं रहती, तब RecyclerView की कार्यप्रणाली वास्तव में सक्रिय हो जाती है। गतिशील सूची के मामले में, हमें यह सोचना होगा कि सूची में कोई आइटम जोड़ने या हटाने पर स्क्रीन पर दिखने वाले दृश्य में क्या परिवर्तन होता है।

रीसाइक्लर व्यू.लेआउट मैनेजर

हमारे व्यू को रैखिक रूप से या ग्रिड में व्यवस्थित करने का निर्णय लेने के अलावा, लेआउट मैनेजर बहुत सारे आंतरिक कार्य करता है।ping रिसाइक्लर को पता होता है कि रिसाइक्लिंग कब करनी है।

यह रखरखाव के लिए जिम्मेदार हैping tracलेआउट मैनेजर स्क्रीन पर वर्तमान में दिखाई दे रहे व्यूज़ की सूची को रिकॉर्ड करता है और इस जानकारी को रीसाइक्लिंग तंत्र को भेजता है। जब उपयोगकर्ता नीचे स्क्रॉल करता है, तो लेआउट मैनेजर रीसाइक्लिंग सिस्टम को शीर्ष पर फोकस से बाहर हो जाने वाले व्यूज़ के बारे में सूचित करने के लिए ज़िम्मेदार होता है ताकि उन्हें पुनः उपयोग किया जा सके, बजाय इसके कि वे वहीं बने रहें और मेमोरी का उपभोग करें या नष्ट होकर नए व्यूज़ बनाएँ।

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

मान लीजिए कि हमारी 100 आइटमों की सूची में से हम शुरुआत में 10 आइटम देख पा रहे हैं, तो लेआउट मैनेजर को पता होता है कि व्यू-0 से लेकर व्यू-9 तक सभी आइटम फोकस में हैं। जैसे-जैसे हम स्क्रॉल करते हैं, लेआउट मैनेजर उन व्यूज की गणना कर पाता है जो फोकस से बाहर हो जाते हैं।

लेआउट मैनेजर इन व्यूज को रीसाइक्लिंग तंत्र में जारी करने में सक्षम है ताकि उनका पुन: उपयोग किया जा सके (उनमें नया डेटा जोड़ा जा सकता है; उदाहरण के लिए, एक व्यू के संपर्क डेटा को हटाया जा सकता है और अगले सेगमेंट से नया संपर्क डेटा प्लेसहोल्डर्स को प्रतिस्थापित कर सकता है)।

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

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

साथ ही, RecyclerView का LayoutManager अपने पास मौजूद डेटा को गलत तरीके से प्रदर्शित नहीं करना चाहता। सही ढंग से काम करने के लिए, LayoutManager निर्धारित अंतराल (60ms) पर RecyclerView.Adapter के साथ सिंक्रनाइज़ होता है, और हमारी सूची आइटमों के बारे में जानकारी साझा करता है, जैसे कि जोड़े गए, अपडेट किए गए, हटाए गए या एक स्थान से दूसरे स्थान पर ले जाए गए आइटम। यह जानकारी प्राप्त होने पर, LayoutManager आवश्यकतानुसार स्क्रीन पर मौजूद सामग्री को परिवर्तनों के अनुरूप पुनर्व्यवस्थित करता है।

RecyclerView से संबंधित कई मुख्य ऑपरेशन RecyclerView.LayoutManager और RecyclerView.Adapter के बीच संचार पर आधारित होते हैं, जो कभी-कभी स्थिर या कभी-कभी गतिशील डेटा की हमारी सूचियों को संग्रहीत करता है।

इसके अलावा, RecyclerView हमें ऐसे तरीके प्रदान करता है जिनका उपयोग हम घटनाओं को सुनने के लिए कर सकते हैं, जैसे कि onBindViewHolder जब हमारा RecyclerView.Adapter हमारी सूची से सामग्री (जैसे कि एक संपर्क) को एक ViewHolder से जोड़ता है ताकि इसका उपयोग स्क्रीन पर जानकारी प्रदर्शित करने के लिए किया जा सके।

एक और फ़ंक्शन है onCreateViewHolder, जो हमें बताता है कि RecyclerView.Adapter कब OneContactView जैसे एक सामान्य View को लेता है और उसे एक ViewHolder आइटम में परिवर्तित करता है जिसके साथ RecyclerView काम कर सकता है।

रीसाइक्लिंग को सक्षम बनाने वाले मूल तंत्रों के अलावा, RecyclerView रीसाइक्लिंग को प्रभावित किए बिना व्यवहार को अनुकूलित करने के तरीके प्रदान करता है। व्यूज़ के पुन: उपयोग से उन सामान्य कार्यों को करना मुश्किल हो जाता है जिन्हें हम स्टैटिक व्यूज़ के साथ करने के आदी हैं, जैसे कि onClick इवेंट्स पर प्रतिक्रिया देना।

जैसा कि हम जानते हैं, RecyclerView.LayoutManager जो उपयोगकर्ता के लिए दृश्य प्रस्तुत करता है, उसमें एक क्षण के लिए आइटमों की एक अलग सूची हो सकती है RecyclerView.Adapter जिसमें सूची डेटाबेस में संग्रहीत होती है या किसी स्रोत से स्ट्रीम होती है। व्यू पर सीधे ऑनक्लिक इवेंट लगाने से अप्रत्याशित व्यवहार हो सकता है, जैसे कि गलत संपर्क को हटाना।

Gradle

यदि हम RecyclerView का उपयोग करना चाहते हैं, तो हमें इसे अपनी build.gradle फ़ाइल में एक डिपेंडेंसी के रूप में जोड़ना होगा। निम्नलिखित उदाहरण में, हमने implementation “androidx.recyclerview:recyclerview:1.1.0” का उपयोग किया है, जो इस लेख के अनुसार सबसे नवीनतम संस्करण है।

हमारे निर्भरता को जोड़ने के बाद Gradle फ़ाइल, हमें द्वारा संकेत दिया जाएगा Android Studio परिवर्तनों को सिंक्रनाइज़ करने के लिए। इसी तरह हमारा Gradle यह फ़ाइल खाली प्रोजेक्ट में केवल डिफ़ॉल्ट सेटिंग्स के साथ एक RecyclerView जोड़ने का काम करेगी।

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.guru99.learnrecycler"
        minSdkVersion 17
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
             'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    implementation "androidx.recyclerview:recyclerview:1.1.0"
}

फिलहाल हमारे पास केवल एक लेआउट फ़ाइल है। हम एक सरल उदाहरण से शुरुआत करेंगे जिसमें हम स्क्रीन पर फलों के नामों की सूची दिखाने के लिए RecyclerView का उपयोग करेंगे।

वस्तुओं की सूचि

हम अपनी MainActivity फ़ाइल पर जाएंगे और सेटअप के दौरान उत्पन्न हुए onCreate() मेथड से ठीक पहले फलों के नामों वाला एक ऐरे बनाएंगे।

package com.guru99.learnrecycler

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

    var fruitNames:Array<String> = arrayOf<String>("Banana", "Mango", "Passion fruit", "Orange", "Grape")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

हमारा अगला लक्ष्य इस सूची को RecyclerView का उपयोग करके स्क्रीन पर प्रदर्शित करना होगा। इसके लिए, हम लेआउट डायरेक्टरी में जाएंगे जहां हमारे लेआउट मौजूद हैं और एक व्यू बनाएंगे जो एक फल को प्रदर्शित करने के लिए जिम्मेदार होगा।

हमारी सूची में प्रत्येक आइटम के लिए उपयोग किया जाने वाला लेआउट

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fruitName"
    />
</TextView>

ऊपर दिए गए TextView में, हमने एक id फ़ील्ड जोड़ा है जिसका उपयोग View की पहचान करने के लिए किया जाएगा। यह डिफ़ॉल्ट रूप से उत्पन्न नहीं होता है। हमने अपने TextView को fruitName id दिया है ताकि इससे जुड़े डेटा से मेल खा सके।

मुख्य लेआउट में रीसाइक्लर दृश्य जोड़ना

इसी गतिविधि में, main_layout.xml नाम की एक लेआउट फ़ाइल है जो डिफ़ॉल्ट रूप से हमारे लिए जेनरेट की गई थी। अगर हम एक खाली प्रोजेक्ट चुनते हैं, तो यह एक अलग फ़ाइल जेनरेट कर देगा। एक्सएमएल इसमें एक ConstraintLayout है और इसके अंदर एक TextView है जिसमें “Hello” टेक्स्ट लिखा होगा। हम इसके सभी कंटेंट्स को हटा देंगे और लेआउट में केवल RecyclerView को ही रखेंगे, जैसा कि नीचे दिखाया गया है:

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView 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:id="@+id/fruitRecyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" />

हमने RecyclerView के लिए एक id एट्रिब्यूट भी जोड़ा है, जिसका उपयोग हम अपने कोड में इसे संदर्भित करने के लिए करेंगे।

android:id="@+id/fruitRecyclerView"

इसके बाद हम वापस अपनी MainActivity फ़ाइल पर जाएँगे। हमने जो आईडी बनाई हैं, उनका उपयोग करके हम उन व्यूज़ को संदर्भित कर सकेंगे जिन्हें हमने अभी बनाया है। हम findViewById() विधि का उपयोग करके RecyclerView को संदर्भित करके शुरुआत करेंगे। Androidहम इसे अपने onCreate() मेथड में करेंगे। हमारा onCreate() मेथड कुछ इस प्रकार दिखेगा।

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    var myFruitRecyclerView: RecyclerView = findViewById(R.id.fruitRecyclerView)
}

व्यूहोल्डर बनाएं

अगले चरण में, हम एक RecyclerView.ViewHolder बनाएंगे, जो हमारे View को ViewHolder में परिवर्तित करने के लिए ज़िम्मेदार होगा। RecyclerView हमारे आइटम प्रदर्शित करने के लिए ViewHolder का उपयोग करता है। हम इसे अपने onCreate() मेथड के ठीक बाद करेंगे।

package com.guru99.learnrecycler

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.RecyclerView

class MainActivity : AppCompatActivity() {

    var fruitNames:Array<String> = arrayOf<String>("Banana", "Mango", "Passion fruit", "Orange", "Grape")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var myFruitRecyclerView: RecyclerView = findViewById(R.id.fruitRecyclerView)
    }

    class FruitViewHolder(fruitView: View): RecyclerView.ViewHolder(fruitView)

}

एक रीसाइक्लर व्यूएडाप्टर बनाएं

अगले चरण में, हम एक FruitArrayAdapter क्लास बनाएंगे जो RecyclerView.Adapter क्लास को एक्सटेंड करेगी। हमारे द्वारा बनाया गया FruitArrayAdapter निम्नलिखित कार्यों के लिए जिम्मेदार होगा: यह फ्रूट एरे से फलों के नाम लेगा, हमारे व्यू one_fruit_view.xml का उपयोग करके एक ViewHolder बनाएगा, फिर फलों को ViewHolder से बाइंड करेगा और कंटेंट को हमारे द्वारा बनाए गए व्यू से डायनामिकली बाइंड करेगा।

package com.guru99.learnrecycler

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.RecyclerView

class MainActivity : AppCompatActivity() {

    var fruitNames:Array<String> = arrayOf<String>("Banana", "Mango", "Passion fruit", "Orange", "Grape")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var myFruitRecyclerView: RecyclerView = findViewById(R.id.fruitRecyclerView)
    }

    class FruitViewHolder(fruitView: View): RecyclerView.ViewHolder(fruitView)

    class FruitArrayAdapter(var fruitArray: Array<String>) : RecyclerView.Adapter<FruitViewHolder>()
}

Android Studio यह हमारे फ्रूटएरेएडेप्टर पर लाल रंग की टेढ़ी-मेढ़ी रेखाएं जोड़ेगा, जो हमें यह बताएगा कि हमें उन विधियों को लागू करने की आवश्यकता है जिनका उपयोग रीसायक्लरव्यू हमारे ऐरे को व्यूहोल्डर से जोड़ने के लिए कर सकता है।

class FruitListAdapter(var fruitArray: Array<String>) : RecyclerView.Adapter<FruitViewHolder>() {
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitViewHolder {

     }

     override fun getItemCount(): Int {

     }

     override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {

     }
 }

हम जनरेट किए गए कोड के सबसे आसान हिस्से, getItemCount() मेथड से शुरुआत करेंगे। हम जानते हैं कि एरे के size प्रॉपर्टी को कॉल करके एरे में आइटम की संख्या कैसे प्राप्त की जाती है।

class FruitListAdapter(var fruitArray: Array<String>) : RecyclerView.Adapter<FruitViewHolder>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitViewHolder {

        }

        override fun getItemCount(): Int {
         return fruitArray.size
        }

        override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {

        }
    }

फिर हम onCreateViewHolder मेथड को इम्प्लीमेंट करेंगे। यहीं पर RecyclerView हमसे FruitViewHolder बनाने में मदद मांगेगा। जैसा कि आपको याद होगा, हमारी FruitViewHolder क्लास कुछ इस तरह दिखती थी:

class FruitViewHolder(fruitView: View): RecyclerView.ViewHolder(fruitView)

इसके लिए हमें फ्रूटव्यू की आवश्यकता है, जिसे हमने one_fruit_view.xml नामक XML फ़ाइल के रूप में बनाया था। हम इस XML का संदर्भ बनाकर इसे निम्नानुसार व्यू में परिवर्तित कर सकते हैं।

class FruitListAdapter(var fruitArray: Array<String>) : RecyclerView.Adapter<FruitViewHolder>() {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitViewHolder {

            var fruitView = LayoutInflater.from(parent.context).inflate(R.layout.one_fruit_view, parent, false)

            var fruitViewHolder = FruitViewHolder(fruitView)

            return fruitViewHolder

        }

        override fun getItemCount(): Int {
            return fruitArray.size
        }

        override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {

        }
    }

शेष भाग onBindViewHolder ओवरराइड है।

fun onBindViewHolder(holder: FruitViewHolder, position: Int)

RecyclerView.Adapter एक पोजीशन इंटीजर मांगता है, जिसका उपयोग हम अपनी सूची से आइटम प्राप्त करने के लिए करते हैं। यह हमें एक होल्डर भी प्रदान करता है ताकि हम फ्रूटएरे से प्राप्त आइटम को व्यू होल्डर के अंदर मौजूद व्यू से जोड़ सकें। व्यू होल्डर के अंदर मौजूद व्यू को ViewHolder.itemView फ़ील्ड के माध्यम से एक्सेस किया जा सकता है। व्यू प्राप्त होने के बाद, हम पहले बनाए गए id fruitName का उपयोग करके कंटेंट सेट कर सकते हैं।

override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {

          var ourFruitTextView = holder.itemView.findViewById<TextView>(R.id.fruitName)

          var aFruitName = fruitArray.get(position)

          ourFruitTextView.setText(aFruitName)
      }

इसके साथ ही, हमारा फ्रूटएरेएडेप्टर पूरा हो गया है और यह इस प्रकार दिखता है।

class FruitListAdapter(var fruitArray: Array<String>) : RecyclerView.Adapter<FruitViewHolder>() {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitViewHolder {

            var fruitView = LayoutInflater.from(parent.context).inflate(R.layout.one_fruit_view, parent, false)

            var fruitViewHolder = FruitViewHolder(fruitView)

            return fruitViewHolder
        }

        override fun getItemCount(): Int {
            return fruitArray.size
        }

        override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {

            var ourFruitTextView = holder.itemView.findViewById<TextView>(R.id.fruitName)

            var aFruitName = fruitArray.get(position)

            ourFruitTextView.setText(aFruitName)
        }
    }

अंत में, हम अपने RecyclerView के शेष हिस्सों को जोड़ने के लिए तैयार हैं, जिसमें एक LayoutManager बनाना शामिल है जो RecyclerView को बताएगा कि सूची की सामग्री को कैसे प्रदर्शित करना है, चाहे LinearLayoutManager का उपयोग करके रैखिक तरीके से दिखाना हो या GridLayoutManager या StaggeredGridLayoutManager का उपयोग करके ग्रिड में दिखाना हो।

लेआउट प्रबंधक बनाएँ

हम वापस अपने onCreate फ़ंक्शन के अंदर जाएंगे और LayoutManager जोड़ेंगे।

override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)

       var myFruitRecyclerView: RecyclerView = findViewById(R.id.fruitRecyclerView)

       var fruitLinearLayout = LinearLayoutManager(this)

       myFruitRecyclerView.layoutManager =fruitLinearLayout

   }

हमारे एडाप्टर को आइटम से जोड़ें और इसे रीसाइक्लर व्यू पर सेट करें

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var myFruitRecyclerView: RecyclerView = findViewById(R.id.fruitRecyclerView)

        var fruitLinearLayout = LinearLayoutManager(this)

        myFruitRecyclerView.layoutManager =fruitLinearLayout

        var fruitListAdapter = FruitListAdapter(fruitNames)

        myFruitRecyclerView.adapter =fruitListAdapter
    }

हमने एक फ्रूटलिस्टएडेप्टर इंस्टेंस भी बनाया है और उसमें फलों के नामों का ऐरे डाला है। और बस, हमारा काम पूरा हो गया है। पूरी मेनएक्टिविटी.kt फ़ाइल इस प्रकार दिखती है।

package com.guru99.learnrecycler

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class MainActivity : AppCompatActivity() {

    var fruitNames:Array<String> = arrayOf<String>("Banana", "Mango", "Passion fruit", "Orange", "Grape")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var myFruitRecyclerView: RecyclerView = findViewById(R.id.fruitRecyclerView)

        var fruitLinearLayout = LinearLayoutManager(this)

        myFruitRecyclerView.layoutManager =fruitLinearLayout

        var fruitListAdapter = FruitListAdapter(fruitNames)

        myFruitRecyclerView.adapter =fruitListAdapter
    }

    class FruitViewHolder(fruitView: View): RecyclerView.ViewHolder(fruitView)

    class FruitListAdapter(var fruitArray: Array<String>) : RecyclerView.Adapter<FruitViewHolder>() {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitViewHolder {

            var fruitView = LayoutInflater.from(parent.context).inflate(R.layout.one_fruit_view, parent, false)

            var fruitViewHolder = FruitViewHolder(fruitView)

            return fruitViewHolder
        }

        override fun getItemCount(): Int {
            return fruitArray.size
        }

        override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {

            var ourFruitTextView = holder.itemView.findViewById<TextView>(R.id.fruitName)

            var aFruitName = fruitArray.get(position)

            ourFruitTextView.setText(aFruitName)
        }
    }
}

प्रोजेक्ट डाउनलोड करें

अक्सर पूछे जाने वाले प्रश्न

RecyclerView, ListView का अधिक लचीला और कुशल उत्तराधिकारी है। यह ViewHolder पैटर्न को लागू करता है, लेआउट मैनेजर के माध्यम से लीनियर, ग्रिड और स्टैगर्ड लेआउट का समर्थन करता है, और इसमें अंतर्निहित आइटम एनिमेशन भी शामिल हैं, जबकि ListView में डिफ़ॉल्ट रूप से इनमें से कोई भी सुविधा नहीं होती है।

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

यह RecyclerView उदाहरण Kotlin में लिखा गया है, जो Google द्वारा आधिकारिक तौर पर अनुशंसित भाषा है। Android विकास। वही RecyclerView, एडाप्टर और लेआउट मैनेजर API भी काम करते हैं। Java.

ViewHolder या onBindViewHolder के अंदर एक क्लिक लिसनर अटैच करें, फिर इसे एक इंटरफ़ेस कॉलबैक के माध्यम से एक्टिविटी या फ़्रैगमेंट को दिखाएँ। ViewHolder की स्थिति का उपयोग करने से क्लिक गलत रीसाइकल्ड आइटम से बाइंड होने से बचते हैं।

DiffUtil एक यूटिलिटी क्लास है जो दो सूचियों के बीच अंतर की गणना करती है और एडॉप्टर को न्यूनतम अपडेट भेजती है। यह गतिशील सूची परिवर्तनों को कुशल बनाती है और जोड़, हटाव और स्थानांतरण को स्वचालित रूप से एनिमेट करती है।

Jetpack Compose नई स्क्रीन के लिए RecyclerView के बजाय LazyColumn और LazyRow का उपयोग करता है। हालांकि, RecyclerView मौजूदा View-आधारित प्रोजेक्ट्स में व्यापक रूप से उपयोग किया जाता है और इंटरऑपरेबिलिटी API के माध्यम से इसे Compose में एम्बेड किया जा सकता है।

जी हां। GitHub Copilot और GPT-आधारित टूल जैसे AI सहायक एक छोटे से प्रॉम्प्ट से RecyclerView एडॉप्टर, ViewHolder और onBindViewHolder बॉयलरप्लेट तैयार कर सकते हैं। डेवलपर्स को फिर भी जेनरेट किए गए कोड की शुद्धता और प्रदर्शन की समीक्षा करनी चाहिए।

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

इस पोस्ट को संक्षेप में इस प्रकार लिखें: