getViewTypeCount और ArrayAdapter की getItemViewType विधियाँ


159

सादे शब्दों में किसी ने मुझसे के उपयोग की व्याख्या कर सकते getViewTypeCount()हैं और getItemViewType()के तरीकों ArrayAdapter?

जवाबों:


308

ये उस मामले को संभालते हैं जहां आप विभिन्न पंक्तियों के लिए विभिन्न प्रकार के दृश्य चाहते हैं। उदाहरण के लिए, एक संपर्क एप्लिकेशन में आप बाईं ओर चित्र और दाईं ओर चित्र रखने के लिए विषम पंक्तियाँ चाहते हैं। उस स्थिति में, आप उपयोग करेंगे:

@Override
public int getViewTypeCount() {
    return 2;
}

@Override
public int getItemViewType(int position) {
    return position % 2;
}

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

यदि आपकी सूची की प्रत्येक पंक्ति में समान लेआउट है, तो आपको दृश्य प्रकारों के बारे में चिंता करने की आवश्यकता नहीं है। वास्तव में, BaseAdapter.java सभी एडेप्टर के लिए एक डिफ़ॉल्ट व्यवहार प्रदान करता है:

public int getItemViewType(int position) {
    return 0;
}

public int getViewTypeCount() {
    return 1;
}

यह वास्तव में आपको हर पंक्ति के लिए समान दृश्य प्रकार प्रदान करता है।

संपादित करें - सामान्य प्रवाह को रेखांकित करने के लिए:

  1. आप AdapterViewएडॉप्टर का उपयोग करके अपने डेटा को बाइंड करते हैं।
  2. AdapterViewउपयोगकर्ता को दिखाई देने वाली वस्तुओं को प्रदर्शित करने का प्रयास करता है।
  3. ढांचा getItemViewTypeपंक्ति के लिए कहता है n, वह पंक्ति जो प्रदर्शित होने वाली है।
  4. रूपरेखा पंक्ति nके प्रकारों के विचारों के लिए अपने पुनर्नवीनीकरण दृश्य पूल की जांच करती है । यह कोई भी खोज नहीं करता है क्योंकि अभी तक कोई भी दृश्य पुनर्नवीनीकरण नहीं किया गया है।
  5. getViewपंक्ति के लिए कहा जाता है n
  6. आप getItemViewTypeपंक्ति के nलिए यह निर्धारित करने के लिए कॉल करते हैं कि आपको किस प्रकार का उपयोग करना चाहिए।
  7. आप एक अलग xml फ़ाइल को बढ़ाने के लिए if / switch स्टेटमेंट का उपयोग करते हैं, जिसके आधार पर व्यू टाइप की आवश्यकता होती है।
  8. आप जानकारी से दृश्य भरें।
  9. आप दृश्य लौटाते हैं, बाहर निकलते हैं getView, और आपकी पंक्ति का दृश्य उपयोगकर्ता को दिखाया जाता है।

अब, जब स्क्रीन को स्क्रॉल करके एक दृश्य को पुनर्नवीनीकरण किया जाता है तो यह पुनर्नवीनीकरण दृश्य पूल में चला जाता है जिसे फ्रेमवर्क द्वारा प्रबंधित किया जाता है। ये अनिवार्य रूप से व्यू टाइप द्वारा आयोजित किए जाते हैं ताकि सही प्रकार का एक दृश्य आपको convertViewअपनी getViewविधि में पैरामीटर में दिया जाए :

  1. फ़्रेम फिर से getItemViewTypeउस पंक्ति के लिए कॉल करता है जिसे वह प्रदर्शित करना चाहता है।
  2. इस बार, उपयुक्त प्रकार के पुनर्नवीनीकरण पूल में एक दृश्य है।
  3. पुनर्नवीनीकरण दृश्य convertViewआपकी getViewविधि के पैरामीटर के रूप में आपको दिया जाता है ।
  4. आप नई जानकारी के साथ पुनर्नवीनीकरण दृश्य को भरते हैं और इसे वापस करते हैं।

1
@ मैथ्यू, आपके उत्तर के लिए धन्यवाद। क्या आप प्रवाह का वर्णन कर सकते हैं कि ये तरीके कैसे लागू होते हैं। इसके अलावा, मुझे यह समझ में नहीं आता कि यह वास्तव में रेस / लेआउट में मेरे डेटा के साथ कैसे जुड़ा हुआ है।
यूजीन

इन विधियों को लागू करने के लिए कोई स्पष्ट अनुबंध नहीं है। रेस / लेआउट दृश्य वस्तुओं के लिए जगह है । यह एक एडॉप्टर है । आपको अपने getView पद्धति में आइटम प्रकार की जांच करनी चाहिए और तदनुसार Res / लेआउट से उचित दृश्य फुलाएं।
मैथ्यू विलिस

1
आप इसे खुद getItemViewType में लौटा रहे हैं।
मैथ्यू विलिस

आप मैन्युअल रूप से getView में एसोसिएशन करते हैं: यदि (टाइप == 0) {/ * फुलाएं R.layout.row_icon_on_left /} और {/ inflate R.layout.row_icon_on_right */}}
मैथ्यू विलिस

75
सावधान रहें! getItemViewType () को 0 और getViewTypeCount () के बीच एक इंट को वापस करना होगा - 1.
PacificSky

12

यदि हमें सूची-दृश्य में विभिन्न प्रकार के दृश्य दिखाने की आवश्यकता है, तो उपयोग में अच्छा है getViewTypeCount()और getItemViewType()एडाप्टर में एक दृश्य को टॉगल करने के बजाय View.GONEऔर View.VISIBLEबहुत महंगा कार्य getView()हो सकता है जो सूची स्क्रॉल को प्रभावित करेगा।

कृपया एडेप्टर में getViewTypeCount()और इसके उपयोग के लिए इसे जांचें getItemViewType()

लिंक: उपयोग-का-प्राप्त- getviewtypecount


GetItemViewType () में IGNORE_ITEM_VIEW_TYPE लौटना, हमेशा सभी दृश्य घटकों को प्राप्त करने के लिए getViewView (int स्थिति, दृश्य देखें, ViewGroup दृश्य समूह) में अशक्त के रूप में 'दृश्य' पास करेगा। क्या यह खराब प्रदर्शन संकेतक नहीं है कि धारक के पैटर्न के मामले में, हम मौजूदा UI विचारों का पुन: उपयोग करते हैं और हम केवल स्थिति के आधार पर View.GONE या View.VISIBLE को देखने के लिए टॉगल कर सकते हैं।
नम्रता बागवाल

11

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

यहाँ मेरी व्याख्या है:
दोनों getViewTypeCount()और getItemViewType()के द्वारा प्रयोग किया जा रहा है BaseAdapterकी getViewविधि पता लगाने के लिए एक दृश्य के प्रकार यह लाने की जानी चाहिए, पुनर्नवीनीकरण और लौट आए। (जैसा कि धागे के भीतर शीर्ष उत्तर में समझाया गया है)। लेकिन अगर आप Android API Doc के अनुसार इन दो तरीकों को सहज रूप से लागू नहीं करते हैं, तो आप उस समस्या में पड़ सकते हैं जिसका मैंने उल्लेख किया था।

कार्यान्वयन के लिए सारांशित दिशानिर्देश:
कई प्रकार की पंक्तियों को लागू करने के Viewsलिए ListViewहमें अनिवार्य रूप से लागू करना होगा, getItemViewType()और getViewTypeCount()विधियाँ। और getItemViewType()प्रलेखन हमें एक नोट इस प्रकार देता है:

नोट: पूर्णांकों सीमा में होना चाहिए 0करने के लिए getViewTypeCount() - 1IGNORE_ITEM_VIEW_TYPEभी लौटाया जा सकता है।

इसलिए आपके लिए getItemViewType()आपको 0 से शुरू होकर, अंतिम प्रकार के रूप में (प्रकारों की संख्या - 1) के लिए मान वापस करने चाहिए। उदाहरण के लिए, मान लें कि आपके पास केवल तीन प्रकार के विचार हैं? इसलिए दृश्य के लिए डेटा ऑब्जेक्ट के आधार पर, आप शून्य-आधारित सरणी इंडेक्स की तरह, केवल 0 या 1 या 2getItemViewType() विधि से वापस कर सकते हैं । और जैसा कि आपके पास तीन प्रकार के विचार हैं, आपकी getViewTypeCount()विधि 3 वापस आनी चाहिए।

किसी भी स्थिति में यदि आप इस विधि के लिए 1, 2, 3 या 111, 222, 333 जैसे किसी अन्य पूर्णांक मान को वापस करते हैं, तो आप निश्चित रूप से उपरोक्त UI बग का अनुभव कर सकते हैं, जिसे आपने केवल Android API Doc का पालन न करके रखा था।

यदि आपको सुराग नहीं मिला है या अभी भी हल नहीं कर सका है और आगे की जानकारी की आवश्यकता है तो कृपया इस StackOverflow Q & A थ्रेड के भीतर मेरा विस्तृत उत्तर पढ़ें ।

आगे की जानकारी के लिए एंड्रॉइड डेवलपर डॉक पढ़ें आपको सीधे सुराग मिल सकता है।

आशा है कि यह उत्तर बहुत सारे घंटे बचाने के लिए किसी के लिए उपयोगी हो सकता है !!!

चीयर्स !!!


1
उल्लेख करने के लिए धन्यवाद IGNORE_ITEM_VIEW_TYPEमेरे पास मेरे एक ListView पर एक बग था। मैंने 1 चित्र और 2 पाठ दृश्य से बना एक दृश्य सम्मिलित करने के लिए एक ArrayAdapter का उपयोग किया। मेरे पास केवल एक दृश्य प्रकार था। मैंने या तो getItemViewType विधि को ओवरराइड नहीं करने की कोशिश की, या फिर स्थिति या हार्ड-कोडर पूर्णांक को वापस करके इसे ओवरराइड करने के लिए। सभी मामलों में, मैं अपनी सूची में डुप्लिकेट का अनुभव कर रहा था, जब अजीब व्यवहार स्क्रॉलिंग (डुप्लिकेट परिवर्तन) के साथ। IGNORE_ITEM_VIEW_TYPEविधि में लौटना समस्या को निर्धारित करता है। धन्यवाद।
एलेक्स

@ ऐलेक्स खुशी है कि यह आपके लिए उपयोगी था! :-)
रंडिका विशमन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.