थोड़ा सा नौसिखिया प्रश्न। getView()
में हमें ViewHolder
क्यों शुरू करना चाहिए? हम इसे निर्माता में क्यों शुरू नहीं कर सकते?व्यूहोल्डर - अच्छा अभ्यास
उत्तर
है आप अस्तित्व में कई ViewHolder
वस्तुओं होगा।
ए ListView
अपनी प्रकृति से नई View
अपनी प्रत्येक पंक्ति के लिए उदाहरण नहीं बनाता है। ऐसा इसलिए है कि यदि आपके पास लाखों चीजों की ListView
है, तो आपको दस लाख चीज़ों के लिए लेआउट जानकारी स्टोर करने की आवश्यकता नहीं है। तो आपको स्टोर करने की क्या ज़रूरत है? बस स्क्रीन पर चीजें हैं। फिर आप उन विचारों को बार-बार पुन: उपयोग कर सकते हैं। इस तरह, आपके ListView
लाख वस्तुओं की संख्या में शायद 10 बच्चे के विचार हो सकते हैं।
अपने कस्टम सरणी अनुकूलक में, आप एक समारोह getView()
कहा जाता है कि कुछ इस तरह दिखता है:
public View getView(int position, View convertView, ViewGroup parent) {
//Here, position is the index in the list, the convertView is the view to be
//recycled (or created), and parent is the ListView itself.
//Grab the convertView as our row of the ListView
View row = convertView;
//If the row is null, it means that we aren't recycling anything - so we have
//to inflate the layout ourselves.
if(row == null) {
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.list_item, parent, false);
}
//Now either row is the recycled view, or one that we've inflated. All that's left
//to do is set the data of the row. In this case, assume that the row is just a
//simple TextView
TextView textView = (TextView) row.findViewById(R.id.listItemTextView);
//Grab the item to be rendered. In this case, I'm just using a string, but
//you will use your underlying object type.
final String item = getItem(position);
textView.setText(item);
//and return the row
return row;
}
यह काम करेंगे, लेकिन एक क्षण ले और देखें कि आप अक्षमता यहाँ पहचान सकते हैं। इस बारे में सोचें कि उपरोक्त में से कौन सा कोड अनावश्यक रूप से बुलाया जाएगा।
समस्या यह है कि हम row.findViewById
को बार-बार कॉल कर रहे हैं, भले ही पहली बार हम इसे देखते हैं, यह कभी नहीं बदलेगा। अगर आपकी सूची में केवल TextView
है, तो शायद यह बुरा नहीं है, यदि आपके पास जटिल लेआउट है, या आपके पास कई दृश्य हैं जिन्हें आप डेटा सेट करना चाहते हैं, तो आप अपना दृश्य ढूंढने में थोड़ी देर खो सकते हैं और एक बार फिर।
तो हम इसे कैसे ठीक कर सकते हैं? खैर, यह देखने के बाद कहीं भी टेक्स्ट व्यू को स्टोर करना समझदारी होगी। इसलिए हम ViewHolder
नामक एक कक्षा पेश करते हैं, जो विचारों को "रखता है"। तो एडाप्टर के अंदर है, तो जैसे एक आंतरिक वर्ग परिचय:
private static class ViewHolder {
TextView textView;
}
इस वर्ग, निजी है, क्योंकि यह एडाप्टर के लिए सिर्फ एक कैशिंग तंत्र है, और यह स्थिर ताकि हम के लिए एक संदर्भ की आवश्यकता नहीं है इसका उपयोग करने के लिए एडाप्टर।
यह हमारे विचार को संग्रहीत करेगा ताकि हमें row.findViewById
कई बार कॉल करने की आवश्यकता न हो। हमें इसे कहां सेट करना चाहिए? जब हम पहली बार दृश्य को बढ़ाते हैं। हम इसे कहां स्टोर करते हैं? दृश्यों में एक कस्टम "टैग" फ़ील्ड होता है, जिसका उपयोग मेटा-सूचना को दृश्य के बारे में स्टोर करने के लिए किया जा सकता है - बिल्कुल वही है जो हम चाहते हैं! तो फिर, अगर हम पहले से ही इस दृश्य को देखा है, हम बस पंक्ति के भीतर से प्रत्येक दृश्य के ऊपर देख के बजाय टैग को देखने के लिए .. है
तो getView()
के अंदर अगर बयान हो जाता है:
//If the row is null, it means that we aren't recycling anything - so we have
//to inflate the layout ourselves.
ViewHolder holder = null;
if(row == null) {
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.list_item, parent, false);
//Now create the ViewHolder
holder = new ViewHolder();
//and set its textView field to the proper value
holder.textView = (TextView) row.findViewById(R.id.listItemTextView);
//and store it as the 'tag' of our view
row.setTag(holder);
} else {
//We've already seen this one before!
holder = (ViewHolder) row.getTag();
}
अब, हमें केवल holder.textView के टेक्स्ट मान को अपडेट करना होगा, क्योंकि यह पहले से ही पुनर्नवीनीकरण दृश्य का संदर्भ है! तो हमारा अंतिम एडाप्टर कोड बन जाता है:
public View getView(int position, View convertView, ViewGroup parent) {
//Here, position is the index in the list, the convertView is the view to be
//recycled (or created), and parent is the ListView itself.
//Grab the convertView as our row of the ListView
View row = convertView;
//If the row is null, it means that we aren't recycling anything - so we have
//to inflate the layout ourselves.
ViewHolder holder = null;
if(row == null) {
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.list_item, parent, false);
//Now create the ViewHolder
holder = new ViewHolder();
//and set its textView field to the proper value
holder.textView = (TextView) row.findViewById(R.id.listItemTextView);
//and store it as the 'tag' of our view
row.setTag(holder);
} else {
//We've already seen this one before!
holder = (ViewHolder) row.getTag();
}
//Grab the item to be rendered. In this case, I'm just using a string, but
//you will use your underlying object type.
final String item = getItem(position);
//And update the ViewHolder for this View's text to the correct text.
holder.textView.setText(item);
//and return the row
return row;
}
और हम कर चुके हैं!
कुछ बातें सोचने के लिए के बारे में:
- कैसे इस परिवर्तन करता है, तो आप एक पंक्ति है कि आप बदलना चाहते हैं में अनेक दृश्य है? एक चुनौती के रूप में, एक ListView जहां प्रत्येक पंक्ति दो
TextView
वस्तुओं और है बनाने के एकImageView
- जब आपके ListView डीबगिंग, कुछ चीजें जाँच इतना है कि आप वास्तव में देख सकते हैं क्या हो रहा है:
- ViewHolder के निर्माता कितनी बार कहा जाता है ।
- क्या
holder.textView.getText()
का मूल्य इससे पहले कि आपgetView()
thnx, भयानक उत्तर – Gorets
कोई समस्या नहीं - अगर सबकुछ समझ में आता है तो मुझे बताएं, व्यूहोल्डर चीज़ ने मुझे थोड़ी देर के लिए भ्रमित कर दिया जब मैंने पहली बार इसके बारे में सीखा। – mindvirus
वाह। उत्कृष्ट जवाब आपके लिए एक चुनौती के रूप में; क्या आप इसे कुछ संदर्भों में सुधार सकते हैं? =) – Qw4z1
जैसे ही हम पंक्ति को पॉप्युलेट करते हैं और प्रत्येक पंक्ति के लिए नई पंक्ति दृश्य बनाते हैं, हमें दृश्य धारक को शामिल करने की आवश्यकता होती है। वैसे ही जैसे मैं तो पंक्ति में दो TextView,
static class ViewHolder {
protected TextView title;
protected TextView type;
}
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.feeds_rowview, null);
final ViewHolder viewHolder = new ViewHolder();
view.setTag(viewHolder);
viewHolder.title = (TextView) view.findViewById(R.id.Title);
viewHolder.type = (TextView) view.findViewById(R.id.Type);
} else {
view = convertView;
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.title.setText(list.get(position).getTitle());
holder.type.setText(list.get(position).getType());
return view;
}
नहीं, प्रत्येक दर्शक के पास अलग-अलग मान होते हैं। जैसा कि हमारे पास पंक्ति में अलग-अलग डेटा है। –
- 1. अच्छा अभ्यास
- 2. एंड्रॉइड: कार्यान्वयन व्यूहोल्डर
- 3. सबसे अच्छा अभ्यास परिणाम
- 4. यह अच्छा अभ्यास संदर्भ
- 5. विरासत डिजाइन। अच्छा अभ्यास?
- 6. अच्छा त्रुटि हैंडलिंग अभ्यास
- 7. जावा enum सबसे अच्छा अभ्यास
- 8. , EJB3 माना सबसे अच्छा अभ्यास
- 9. प्रश्न में अच्छा अभ्यास है?
- 10. अच्छा अभ्यास: शुद्ध वर्चुअल विधि
- 11. क्या व्यूहोल्डर को व्यूहोल्डर पैटर्न में स्थिर के रूप में प्रदर्शन के लिए महत्वपूर्ण है?
- 12. लुसीन अच्छा अभ्यास और धागा सुरक्षा
- 13. क्या JQuery नेमस्पेस एक अच्छा अभ्यास है?
- 14. जावा - क्या यह अच्छा प्रोग्रामिंग अभ्यास है?
- 15. Capistrano विन्यास प्रबंधन के लिए अच्छा अभ्यास?
- 16. जावा अपवादों के लिए अच्छा अभ्यास
- 17. अच्छा अभ्यास - मॉडल में पुनर्निर्देशन? - रेल 3.1
- 18. उदाहरण के लिए एक अच्छा अभ्यास है?
- 19. सबसे अच्छा अभ्यास फ़ॉन्ट आकार मोबाइल
- 20. डीएओ पैटर्न के लिए सबसे अच्छा अभ्यास?
- 21. django + Pymongo पूलिंग का सबसे अच्छा अभ्यास?
- 22. जावास्क्रिप्ट ऑब्जेक्ट निर्माण सबसे अच्छा अभ्यास
- 23. सी ++ सिंगलटन वर्ग - विरासत अच्छा अभ्यास
- 24. टैब नेविगेशन के लिए सबसे अच्छा अभ्यास?
- 25. Lucene और एसक्यूएल सर्वर - सबसे अच्छा अभ्यास
- 26. एंड्रॉयड TCP कनेक्शन सबसे अच्छा अभ्यास
- 27. सी ++ (आलसी मूल्यांकन) में अच्छा अभ्यास
- 28. स्कैला इंस्टेंस चर सबसे अच्छा अभ्यास
- 29. व्यूहोल्डर पैटर्न में क्यों ViewHolder क्लास स्थिर होना चाहिए?
- 30. त्वरित लोडिंग सूची दृश्य, व्यूहोल्डर विधि से तेज़
http://www.youtube.com/watch?v=wDBM6wVEO70 के अंत में इसे अद्यतन है। इस वीडियो पर एक नज़र डालें। अपने प्रश्न का उत्तर देना चाहिए। – Raghunandan