2013-04-16 13 views
5

तो जाने-माने ViewHolder आमतौर पर उपयोग करते हुए पैटर्न (ListAdapter) की तरह दिखता है:बारे ListView में ViewHolder पैटर्न कार्यान्वयन अनुकूलन

... 

    @Override 
    public View getView(final int position, View convertView, final ViewGroup parent) { 

     final Album album = albums.get(position); 

     ViewHolder viewHolder = null; 
     if (convertView==null){ 
      convertView = inflater.inflate(R.layout.albums_list_item, null); 

      final ImageView albumImage = (ImageView) convertView.findViewById(R.id.album_icon); 

      final TextView txtTitle = (TextView) convertView.findViewById(R.id.album_title); 

      final TextView txtDescription = (TextView) convertView.findViewById(R.id.album_copyright); 

      viewHolder = new ViewHolder(); 
      viewHolder.albumImage = albumImage; 
      viewHolder.txtTitle = txtTitle; 
      viewHolder.txtDescription = txtDescription; 
      convertView.setTag(viewHolder); 
     } 
     else 
      viewHolder = (ViewHolder)convertView.getTag(); 

     viewHolder.txtTitle.setText(album.getTitle(locale)); 
     viewHolder.txtDescription.setText(album.getCopyrightInfo(locale)); 
     ... 
     return convertView; 
    } 

जबकि ViewHolder वर्ग आमतौर पर ऐसा दिखता है:

static class ViewHolder{ 
    public ImageView previewImage; 
    public TextView txtTitle; 
    public TextView txtDescription; 
} 

मेरे सवालों का ViewHolder कार्यान्वयन के बारे में है।
1) यह हर क्षेत्र को शुरू करने के बजाय कन्स्ट्रक्टर का उपयोग क्यों नहीं करता है?
2) यह सुरक्षित के बजाय डिफ़ॉल्ट पहुंच प्रकार का उपयोग क्यों करता है (वास्तव में इसे निजी होना चाहिए लेकिन यह जेआईटी द्वारा बनाए गए स्थिर एक्सेसर्स के कारण प्रदर्शन को प्रभावित करता है)? खैर, मुझे लगता है कि यह केवल विरासत के बारे में है।

protected static class ViewHolder{ 
    public final ImageView previewImage; 
    public final TextView txtTitle; 
    public final TextView txtDescription; 

    public ViewHolder (final ImageView previewImage, final TextView txtTitle, final TextView txtDescription){ 
     this.previewImage = previewImage; 
     this.txtTitle = txtTitle; 
     this.txtDescription = txtDescription; 
    } 
} 

और ListAdapter में केवल परिवर्तन है:

... 
final TextView txtDescription = (TextView) convertView.findViewById(R.id.album_copyright); 
viewHolder = new ViewHolder(albumImage, txtTitle, txtDescription); 
convertView.setTag(viewHolder); 
... 

वैसे भी यह एक निर्माता कॉल करना होगा
तो क्यों निम्नलिखित पैटर्न बेहतर नहीं (छोड़कर "डिफ़ॉल्ट बनाम संरक्षित" पहुँच प्रकार) है। क्या यह सिर्फ स्वाद का मामला है? या यह संस्करण किसी भी तरह धीमा है या यह किसी तरह से प्रदर्शन को प्रभावित करता है?

उत्तर

2

मुझे लगता है कि यह सिर्फ स्वाद का मामला है। मेरे लिए यह मानक मानक भी बेहतर दिखता है। अंतिम चर का उपयोग करने के कारण भी आपका संस्करण संभवतः तेज़ होगा।

+0

धन्यवाद, वैसे ही मैं इसके बारे में सोच रहा हूं। – Stan

1

मेरी राय में यह करने का सबसे अच्छा तरीका है, लेकिन ऐसा कुछ है जिसे मैं अपना कोड बदलूंगा। आपके ViewHolder में एक कन्स्ट्रक्टर है जहां आप विचार सेट कर रहे हैं, लेकिन जैसा कि मैं देख सकता हूं कि आप इसे अपने कोड में उपयोग नहीं कर रहे हैं। मैं इसका इस्तेमाल करूंगा या बस इसे हटा दूंगा। और एक anothet बात है, वास्तव में एक ही प्रभाव प्राप्त करने के लिए एक बेहतर तरीका है, लेकिन यह केवल Android पर काम करेंगे 4:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

    ImageView mIcon; 
    TextView mName; 
    if (convertView == null) { 
     convertView = LayoutInflater.from(context) 
      .inflate(R.layout.my_contact_listing, parent, false); 
     mIcon = (ImageView) convertView.findViewById(R.id.contact_icon); 
     mName = (TextView) convertView.findViewById(R.id.contact_name); 
     convertView.setTag(R.id.contact_icon, mIcon); 
     convertView.setTag(R.id.contact_name, mName); 
    } else { 
     mIcon = (ImageView) convertView.getTag(R.id.contact_icon); 
     mName = (TextView) convertView.getTag(R.id.contact_name); 
    } 

    Contact mContact = getItem(position); 
    mName.setText(mContact.getName()); 
    mIcon.setImageResource(mContact.getIcon()); 

    return convertView; 
} 
+0

धन्यवाद। लेकिन क्या यह व्यूहोल्डर विचारों का उपयोग नहीं करता है? ("लेकिन जैसा कि मैं देख सकता हूं कि आप इसे अपने कोड में उपयोग नहीं कर रहे हैं"): viewHolder.txtTitle.setText (album.getTitle (लोकेल)); viewHolder.txtDescription.setText (album.getCopyrightInfo (लोकेल)); – Stan

+0

बिल्कुल, आप इसे प्राप्त करने के लिए व्यू की सेटटैग विधि का उपयोग कर सकते हैं: http://developer.android.com/reference/android/view/View.html#setTag(int, java.lang.Object), संदर्भों के लिए। – hardartcore

+0

क्या आपका मतलब कोड कोड है: convertView.setTag (viewHolder) ;? मैंने इस लाइन को नहीं दिखाया क्योंकि मूल की तुलना में कोई बदलाव नहीं है। ListAdapter में एकमात्र परिवर्तन ViewHolder निर्माण और इसके फ़ील्ड प्रारंभिक है। – Stan

5

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

private class ViewHolder 
    { 
     protected final ImageView image; 
     protected final TextView title; 
     protected final TextView status; 

     public ViewHolder(final View root) 
     { 
     image = (ImageView) root.findViewById(R.id.artist_image); 
     title = (TextView) root.findViewById(R.id.artist_title); 
     status = (TextView) root.findViewById(R.id.artist_status); 
     } 
    } 

और getView(...)

View row = convertView; 

    if (null == row || null == row.getTag()) 
    { 
    row = inflater.inflate(R.layout.adapter_artists, null); 
    holder = new ViewHolder(row); 
    row.setTag(holder); 
    } 
    else 
    { 
    holder = (ViewHolder) row.getTag(); 
    } 

में मैं इसे इस तरह से करना पसंद है क्योंकि यह मेरी एडाप्टर कोड getView(...) में सरल रहता है और अंतिम चर का लाभ है। मुझे शायद इसे नाबालिग स्पीड बूस्ट मिल जाए, जिससे इसे संरक्षित किया जा सके लेकिन मुझे लगता है कि प्रदर्शन बड़ी सूची के साथ भी पर्याप्त है।

+3

लेकिन वे (एंड्रॉइड । रोमैन गाय जैसे डेवलपर लोग कहते हैं कि व्यूहोल्डर स्थिर वर्ग (प्रदर्शन का मामला) होना चाहिए और निजी एक्सेस प्रकार का उपयोग करने का भी बुरा विचार होना चाहिए यदि एडाप्टर के लिए बाहरी कक्षा (और इसके बाद से 2 बी स्थिर है, यह आंतरिक नहीं हो सकता है एडाप्टर) इसे निजी से व्यापक होना चाहिए (वे ऊपर उल्लिखित डिफ़ॉल्ट पहुंच प्रकार का उपयोग करते हैं)। – Stan

+0

हाँ मुझे इसके बारे में कुछ याद रखना याद है, मेरे पास प्रदर्शन के साथ अच्छा प्रयोग नहीं है। यह कन्स्ट्रक्टर पैटर्न है जिसे मैं दिखाना चाहता था, फिर आपको यह सुनिश्चित करने का मुद्दा मिलता है कि स्थिर होने के बाद कोई अन्य वर्ग इसे एक्सेस नहीं कर सकता है। क्या स्थिर संरक्षित नौकरी करने के लिए पर्याप्त सीमित है? – ScouseChris

+0

निजी के निकटतम पहुंच प्रकार सुरक्षित है इसलिए हाँ। मुझे आपका दृष्टिकोण पसंद है और अब इसका इस्तेमाल करने के लिए मेरा कोड बदल रहा है। कोड कैसा दिखता है इसके बारे में कोई वास्तविक अंतर नहीं है। Cuz बस पैरामीटर के गुच्छा के बजाय 1 पैरामीटर भेजने के बारे में। हालांकि यह युग्मन और एकजुटता उल्लंघन है, लेकिन व्यूहोल्डर एडाप्टर के लिए उपग्रह-वर्ग की तरह है, इसलिए यह एक बड़ा सौदा नहीं है। – Stan

संबंधित मुद्दे