2010-07-07 5 views
8

मैंने कई बार और सभी उत्तरों नामक getView के मुद्दे के बारे में पढ़ा है। हालांकि, मुझे मेरी समस्या का समाधान नहीं मिला है।एंड्रॉइड एडाप्टर एकाधिक getView

मेरे पास एक सूची है जहां पंक्तियों में दो राज्य हैं: पढ़ें या नहीं। खैर, मैं पहली बार देखे गए आइटमों को एक अलग रंग रखना चाहता हूं और जब मैं सूची को स्क्रॉल करता हूं, तो वे अपना रंग "राज्य पढ़ना" में बदल देते हैं।

ऐसा करने के लिए, विधि में प्राप्त करें मेरे एडाप्टर का दृश्य मैं एक फ़ील्ड सेट करता हूं जब उस आइटम की पंक्ति पेंट की जाती है। लेकिन समस्या निम्न है: चूंकि विधि getView को कई बार कहा जाता है क्योंकि फ़ील्ड को पढ़ने के रूप में चिह्नित किया जाता है और जब स्क्रीन में सूची दिखाई जाती है तो ऐसा प्रतीत होता है जैसे इसे पहले ही पढ़ा जा चुका है।

इस समस्या को हल करने के लिए कोई विचार?

धन्यवाद

उत्तर

14

मुझे लगता है कि आप getView के मुद्दे को कई बार एक ही दृश्य का अनुरोध करने का मतलब मानते हैं। क्योंकि यह विभिन्न कारणों के लिए विचारों के लिए माप (स्क्रॉलबार आकार, लेआउट, आदि)

यह समस्या आमतौर पर अपने सूचीदृश्य पर "wrap_content" संपत्ति का उपयोग नहीं कर से बचा जा सकता होने की जरूरत है

ListView करता है।

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

उस डेटा के प्रदर्शन के रूप में दृश्य की अवधारणा के अलावा दृश्य और डेटा के बीच किसी भी रिश्ते से बचने का प्रयास करें।

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

+0

"डेटा को अद्यतन, और अपने एडाप्टर पर dataSetChanged फोन" - मेरे लिए काम करता –

0

जिस तरह से आप इसे काम करना चाहते हैं। कारण getView() को ओएस को पंक्तियों को मापने की अनुमति देने के लिए कई बार कहा जाता है, इसलिए यह जानता है कि उन्हें कैसे बाहर रखा जाए। जब आप इसे क्लिक करते हैं या बॉक्स या कुछ चेक करते हैं तो आपको इसे पढ़ने के रूप में चिह्नित करना होगा।

1

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

public class ImageAdapter extends BaseAdapter { 
    private Context mContext; 
    private List<Integer> usedPositions = new ArrayList<Integer>(); 

    public ImageAdapter(Context c, List<String> imageUrls) { 
     mContext = c; 
     ... 
    } 

    ... 

    // create a new ImageView for each item referenced by the Adapter 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ImageView imageView; 
     if (convertView == null) { 
      imageView = new ImageView(mContext); 
      imageView.setLayoutParams(new GridView.LayoutParams(85, 85)); 
      imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
      imageView.setPadding(8, 8, 8, 8); 
     } else { 
      imageView = (ImageView) convertView; 
     } 

     if (!usedPositions.contains(position)) { 
      // Your code to fill the imageView object content 
      usedPositions.add(position); // holds the used position 
     } 

     return imageView; 
    } 
} 
0

डबल कॉल से बचने का एक बहुत ही आसान तरीका है जब आप कोड के इस ब्लॉक के नीचे कुछ भी नहीं जानते हैं तो लेआउट विकृत हो जाएगा।

private static List<String> usedPositions = new ArrayList<String>(); 

...

@Override 
public View getView(int position, View rowView, ViewGroup parent) { 
    rowView = inflater.inflate(R.layout.download_listview_item, null); 

    Log.d(LOG_TAG, "--> Position: " + position); 

    if (!usedPositions.contains(String.valueOf(position))){ 
     usedPositions.add(String.valueOf(position)); 
     return rowView; 
    }else{ 
     usedPositions.remove(String.valueOf(position)); 
    } 

...