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

RecyclerView क्या है? Android?

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

दृश्य

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

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

समूह देखें

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

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

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 anology, we can now group views 
//together and the structure that would hold that would be what we call the ViewGroup

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

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

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

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

लीनियर लयआउट

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

यहाँ कुछ छवियाँ दी गई हैं जो केन्द्रीकरण को समझने में सहायक हैं। हम इसे 200px x 200px स्थान के अंदर एक सरल TextView मानेंगे, केन्द्रीकरण विशेषताएँ इसे निम्न प्रकार से व्यवहार करने देंगी।

android:center_horizontal

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

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

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

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

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

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

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

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

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

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

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

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

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

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

class AmericanCharger() {
    var chargingPower = 10
}
class BritishCharger(){
    var charginPower = 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 charingPower:Int = charger.chargingPower / 2
           var newBritishCharger = new BritishCharger()
           newBritishCharger.chargingPower = theAmericanCharger.chargingPower/2
        
        return newBritishCharger
    }
}

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

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

americanChargerIFound के साथ myBritishDevice में चार्ज() विधि को कॉल करने का प्रयास काम नहीं करेगा क्योंकि 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(theAmericanCharger)
//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 x 2 ग्रिड हो सकता है।

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

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

बड़ी सूचियाँ

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

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

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

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

 <ContactList>
</ContactList>

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

यदि ऐसा है भी, तो यह तरीका नहीं है जिससे रीसाइक्लर व्यू में चाइल्ड व्यू जोड़े जाते हैं।

हमारे उपयोग के मामले में, हमारे पास संपर्कों की एक लंबी सूची होगी। सूची में प्रत्येक संपर्क के लिए, हमें OneContactView बनाना होगा और हमारे संपर्क वर्ग में फ़ील्ड से मिलान करने के लिए दृश्य के अंदर डेटा को पॉप्युलेट करना होगा। फिर एक बार जब हमारे पास दृश्य हो जाता है, तो हमें सूची दिखाने के लिए इसे 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 में हमें इसमें दृश्य जोड़ने होंगे ताकि यह हमें इसकी रीसाइक्लिंग क्षमता में मदद कर सके।

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

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

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

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

लेकिन इस परिदृश्य में, अब हमारे पास RecyclerView.Adapter वर्ग है, जिसमें ViewHolders बनाने की एक विधि है।

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

RecyclerView.ViewHolder एक अमूर्त वर्ग है जो हमारे दृश्य को एक तर्क के रूप में लेता है और इसे ViewHolder में परिवर्तित करता है।

यह रैपर पैटर्न का उपयोग करता है जिसका उपयोग कक्षाओं की क्षमताओं को बढ़ाने के लिए किया जाता है।

ग्राउंडवर्क #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()
    }

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

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

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"

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

ऊपर दिए गए हमारे मामले में, हमने एक ठोस वर्ग का उपयोग किया। इसे एक सार वर्ग में भी लागू करना संभव है। हमें बस इतना करना होगा कि स्पीचपावर्डएनिमलबायरैपर वर्ग को सार में बदलना है और हमारा काम हो गया। हम इसे अधिक पठनीय बनाने के लिए वर्ग का नाम कुछ छोटा कर देंगे।

abstract class SpeechPowered(var myAnimal:Animal){

    fun sound(){
        myAnimal.sound()
    }

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

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

हमारे उदाहरण में, हम एक क्लास 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 क्लास एक अमूर्त क्लास है जो View में कार्यक्षमता जोड़ता है, ठीक वैसे ही जैसे हमने जानवरों में स्पीक विधि जोड़ी है। जोड़ी गई कार्यक्षमता ही RecyclerView के साथ काम करते समय इसे काम करने में सक्षम बनाती है।

इस प्रकार हम 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)

रीसाइक्लर व्यू में एक एडाप्टर है जो हमें हमारे संपर्क सरणी को रीसाइक्लर व्यू के साथ संपर्क दृश्य से जोड़ने की अनुमति देता है

दृश्य जोड़ना

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

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

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

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

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

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

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

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

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

लेआउट कॉल का एक उदाहरण है scrollToPosition

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

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

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

ग्राउंडवर्क #4. कॉलबैक

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

रीसाइक्लर व्यू के लिए कच्चा माल हमारे व्यूज़ (जैसे वनकॉन्टैक्ट व्यू) और डेटा स्रोत हैं।

contactList:Array<Contact>

हमने एक सरल परिदृश्य को प्रारंभिक बिंदु के रूप में प्रयोग किया है, ताकि यह समझा जा सके कि RecyclerView क्या हासिल करने का प्रयास कर रहा है।

एक आधारभूत स्थिति यह है कि जब हमारे पास 1000 संपर्कों की एक स्थिर सरणी होगी जिसे हम उपयोगकर्ता को दिखाना चाहते हैं, तो इसे समझना आसान है।

रीसाइक्लरव्यू मशीनरी वास्तव में तब सक्रिय होना शुरू होती है जब सूची स्थिर नहीं रहती।

गतिशील सूची में, हमें यह सोचना होगा कि जब हम सूची में कोई आइटम जोड़ते हैं या सूची से कोई आइटम हटाते हैं तो स्क्रीन पर दृश्य का क्या होता है।

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

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

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

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

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

लेआउट मैनेजर इन दृश्यों को रीसाइक्लिंग तंत्र में जारी करने में सक्षम है, ताकि उनका पुनः उपयोग किया जा सके (नया डेटा उनसे जोड़ा जा सके, जैसे कि दृश्य का संपर्क डेटा हटाया जा सकता है और अगले खंड से नया संपर्क डेटा प्लेसहोल्डर्स को प्रतिस्थापित कर सकता है)।

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

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

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

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

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

दूसरा onCreateViewHolder है, जो हमें बताता है कि RecyclerView कब काम करता है। एडाप्टर OneContactView जैसा कोई सामान्य दृश्य लेता है और उसे ViewHolder आइटम में बदल देता है, जिसके साथ RecyclerView काम कर सकता है। RecyclerView द्वारा उपयोग के लिए हमारे ViewHolder से। onViewDetached

रीसाइक्लिंग को सक्षम करने वाले मुख्य तंत्रों के अलावा, रीसाइक्लर व्यू रीसाइक्लिंग को प्रभावित किए बिना व्यवहार को अनुकूलित करने के तरीके प्रदान करता है।

दृश्यों का पुनः उपयोग करने से उन सामान्य कार्यों को करना कठिन हो जाता है जिन्हें हम स्थैतिक दृश्यों के साथ करने के आदी हैं, जैसे कि onClick घटनाओं पर प्रतिक्रिया करना।

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

Gradle

यदि हम RecyclerView का उपयोग करना चाहते हैं, तो हमें इसे अपनी build .gradle फ़ाइल में निर्भरता के रूप में जोड़ना होगा।

निम्नलिखित उदाहरण में हमने कार्यान्वयन “androidx.recyclerview:recyclerview:1.1.0” का उपयोग किया है जो इस लेख के अनुसार सबसे वर्तमान संस्करण है।

हमारे निर्भरता को जोड़ने के बाद Gradle फ़ाइल, हमें द्वारा संकेत दिया जाएगा Android स्टूडियो से Syncपरिवर्तनों का महिमामंडन करें,

ऐसा ही हमारा है 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)
    }
}

हमारा अगला लक्ष्य इस सूची को रीसाइक्लर व्यू का उपयोग करके स्क्रीन पर प्रस्तुत करना होगा।

ऐसा करने के लिए, हम लेआउट डायरेक्टरी पर जाएंगे जिसमें हमारे लेआउट्स हैं और एक दृश्य बनाएंगे जो एक फल को दिखाने के लिए जिम्मेदार होगा।

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

<?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 रखी है, जो इससे जुड़ी होगी।

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

उसी गतिविधि में, main_layout.xml लेआउट फ़ाइल है जो हमारे लिए डिफ़ॉल्ट रूप से तैयार की गई थी।

यदि हम एक खाली प्रोजेक्ट चुनते हैं। तो यह एक उत्पन्न होगा एक्सएमएल जिसमें ConstraintLayout होगा और अंदर "Hello" टेक्स्ट वाला एक TextView होगा।

हम सभी सामग्री को हटा देंगे और लेआउट में केवल 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 हमारे आइटम प्रदर्शित करने के लिए करता है।

हम यह कार्य अपने fun 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 से बाँध देगा, और गतिशील रूप से सामग्री को हमारे द्वारा बनाए गए व्यू one_fruit_view.xml से बाँध देगा।

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 स्टूडियो हमारे FruitArrayAdapter पर लाल रंग की घुमावदार रेखाएं जोड़ देगा, जो हमें बताएगा कि हमें एक ऐसी विधि को क्रियान्वित करने की आवश्यकता है, जिसका उपयोग RecyclerView हमारे ऐरे को ViewHolder से जोड़ने के लिए कर सके, जिसका उपयोग RecyclerView कर सके।

   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() विधि है। हम जानते हैं कि array.length विधि को कॉल करके हमारे ऐरे में आइटम की संख्या कैसे प्राप्त करें।

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) {
          
        }
    }

फिर हम override fun onCreateViewHolder विधि को क्रियान्वित करेंगे।

यहीं पर RecyclerView हमसे FruitHolder के निर्माण में सहायता करने के लिए कहता है।

यदि हम याद करें तो हमारा FruitViewHolder वर्ग इस प्रकार दिखता था:

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

इसके लिए हमारे fruitView की आवश्यकता है जिसे हमने xml फ़ाइल one_fruit_view.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) {

        }
    }

शेष बिट ओवरराइड है

fun onBindViewHolder(holder: FruitViewHolder, position: Int)

RecyclerView.Adapter एक स्थिति पूर्णांक के साथ पूछता है, जिसका उपयोग हम अपनी सूची से एक आइटम लाने के लिए करेंगे। यह हमें एक धारक भी प्रदान करता है ताकि हम fruitArray से प्राप्त आइटम को व्यू होल्डर के अंदर रखे जा रहे व्यू से बांध सकें।

ViewHoder के अंदर रखा गया दृश्य ViewHolder.itemView फ़ील्ड के ज़रिए एक्सेस किया जा सकता है। एक बार जब हमें दृश्य मिल जाता है, तो हम सामग्री सेट करने के लिए पहले बनाई गई आईडी 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)
        }

इसके साथ ही हमारा FruitArrayAdapter पूरा हो गया है और इस प्रकार दिखता है।

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
    }

हमने एक fruitListAdapter इंस्टैंस भी बनाया है और उसमें फलों के नामों की सरणी भी डाली है।

और मूलतः, हमारा काम पूरा हो गया।

संपूर्ण MainActivity.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)
        }
    }
}

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