2012-05-20 3 views
7

मेरे पास एंड्रॉइड में एक ग्रिड व्यू है जिसे मैं इसे एक्सएमएल संसाधन से पुनर्प्राप्त डेटा के साथ भरता हूं।
उदाहरण के लिए मेरे पास ग्रिड व्यू में 15 आइटम हैं जो क्रम में रखे गए हैं। कुल ऊंचाई स्क्रीन की ऊंचाई से अधिक है इसलिए मुझे बाकी वस्तुओं को देखने के लिए स्क्रॉल करना होगा।
समस्या तब होती है जब मैं बैक अप करता हूं, अदृश्य पंक्तियों का क्रम बदल गया है। यह एक रहस्यमय व्यवहार है क्योंकि कभी-कभी आइटम एक दूसरे के साथ पंक्तियों को स्वैप करते हैं।Android GridView में स्क्रॉल करने पर आइटम क्यों ऑर्डर बदलते हैं?

public class ImageAdapter extends BaseAdapter { 
     public ImageAdapter(Context c, NodeList cuu) { 
       cu = cuu; 
     } 
     public int getCount() { 
       Log.d("Node Count",cu.getLength()+""); 
       return cu.getLength(); 
     } 
     public Object getItem(int position) { 
       return position; 
     } 
     public long getItemId(int position) { 
       return position; 
     } 
     public View getView(int position, View convertView, ViewGroup parent) { 
       View myView = convertView; 
       if (convertView == null) { 
        Node nd = cu.item(position); 
        Log.d("nodes","Pos: "+(position)+" Name: "+nd.getNodeName()+" Title: "+nd.getAttributes().getNamedItem("title").getTextContent()); 
        int catID = Integer.parseInt(nd.getAttributes().getNamedItem("id").getTextContent()); 
        LayoutInflater li = getLayoutInflater(); 
        myView = li.inflate(R.layout.grid_item, null); 
        ImageView imageView = (ImageView) myView.findViewById(R.id.grid_item_image); 
        myView.setLayoutParams(new GridView.LayoutParams(70, 100)); 
        id.download(nd.getAttributes().getNamedItem("icon").getTextContent(),imageView); 
        TextView textView = (TextView) myView.findViewById(R.id.grid_item_text); 
        textView.setText(nd.getAttributes().getNamedItem("title").getTextContent()); 
        myView.setTag((Object) catID); 
       }else{ 
        //Log.d("nodes","Pos: "+(position)); 
       } 
       return myView; 
     } 
     private NodeList cu = null; 
    } 

अपडेट:: खैर, यह है बल्कि अजीब यहाँ मेरी getView तरीका है। कुछ और डिबगिंग के बाद मैंने देखा कि ग्रिड व्यू में, एडाप्टर 13 वां स्थान छोड़ देता है, जिसका अर्थ है कि यह 13 के बजाय 1 लौटाता है और फिर 14 पर चलता है !!! (मुझे लगता है कि 13 दुर्भाग्य है!)

+0

'एडाप्टर' स्थिति स्वयं को छोड़ नहीं पाएगा। अपने एडाप्टर के लिए पूरा कोड पोस्ट करें। – Luksprog

+0

ठीक है, मैंने पूरे एडाप्टर को वहां रखा है। –

उत्तर

5

हैं कि सभी कोड आप getView विधि आप इसे सही कार्यान्वित नहीं कर रहे में है:

public View getView(int position, View convertView, ViewGroup parent) { 
     View myView = convertView; 
     if (myView == null) {   
      Node nd = cu.item(position); 
      int catID = Integer.parseInt(nd.getAttributes().getNamedItem("id") 
        .getTextContent()); 
      LayoutInflater li = getLayoutInflater(); 
      myView = li.inflate(R.layout.grid_item, null); 
      myView.setLayoutParams(new GridView.LayoutParams(70, 100));   
      myView.setTag((Object) catID); 
     } 
     Node nd = cu.item(position); 
     Log.d("nodes", "Pos: " + (position) + " Name: " + nd.getNodeName() 
       + " Title: " 
       + nd.getAttributes().getNamedItem("title").getTextContent()); 
     ImageView imageView = (ImageView) myView 
       .findViewById(R.id.grid_item_image); 
     id.download(nd.getAttributes().getNamedItem("icon") 
       .getTextContent(), imageView); 
     TextView textView = (TextView) myView 
       .findViewById(R.id.grid_item_text); 
     textView.setText(nd.getAttributes().getNamedItem("title") 
       .getTextContent()); 
     return myView; 
    } 

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

  • यदि यह null है यह इस GridView के तत्व के लिए एक नया View को बढ़ाने के लिए समय आ गया है: convertViewnull है

    • जांच करें कि। आप Views लिखने के लिए कैश करने के लिए धारक पैटर्न का भी उपयोग कर सकते हैं (findViewById हर बार खोज के बजाय) (आप setTag तत्व का उपयोग फुले हुए दृश्य के लिए करते हैं लेकिन यह Node डेटा तत्व से डेटा का एक टुकड़ा है?!? आप क्या योजना बनाते हैं इसके साथ करने के लिए?!)
    • यदि ऐसा नहीं है null आप कुछ नहीं कर देंगे (या यदि आप धारक पैटर्न को लागू आप के साथ पहले से ही Views खोजा टैग मिलेगा)

और यह आपको क्या करना चाहिए है कि अगर/किसी और बयान

  • आप ऊपर भाग के बाद में डेटा के साथ Views पॉप्युलेट होगी (ऐसा वे उस पद के लिए apropriate डेटा पकड़)।
+0

धन्यवाद, ऐसा इसलिए है क्योंकि मैं एंड्रॉइड प्रोग्रामिंग के लिए बिल्कुल नया हूं। आपकी मदद से मैं इसे काम पर ला सकता हूं। –

+1

ty! तुमने मुझे एक दिन बचाया – Spyros

3

आपका एडाप्टर कार्यान्वयन घातक रूप से त्रुटिपूर्ण है।

getView() में, convertViewnull है, तो आप एक लेआउट बढ़ाते हैं और इसके विजेट को पॉप्युलेट करते हैं। यह ठीक है।

getView() में, convertViewnull नहीं है, तो आप बिल्कुल कुछ भी नहीं करते हैं। यह बहुत गलत है।

क्या आप चाहिएgetView() में, कर रहा है, तो convertViewnull नहीं है, अभी भी सेल के विगेट्स पॉप्युलेट है। convertView का प्रतिनिधित्व करता है एक सेल, पुनर्नवीनीकरण किया जा करने के लिए ताकि आप मुद्रास्फीति को छोड़ और सीपीयू समय बचा सकते हैं, लेकिन आप अभी भी है कि सेल के विगेट्स अद्यतन करने के लिए प्रतिबिंबित करने के लिए जो कुछ भी स्थिति आप इस विशिष्ट getView() कॉल में की स्थापना किए जाने की अपेक्षा की जाती है की है।

+0

मुझे एक ही समस्या है लेकिन मैंने व्यूहोल्डर लागू किया, और फिर भी छवियों का मेरा क्रम बदल रहा था। – Mikey

+0

@ कॉमन्सवेयर क्या यह सच है कि 'findViewById()' सहित सभी कार्रवाइयां बाहर की जानी चाहिए यदि/else? किसी ने कहा कि यहां और यह जानकारी मेरे लिए नई है। – sandalone

+1

@ सैंडलोन: ** प्रत्येक कॉल 'getView()' पर आपको पंक्ति ** को कॉन्फ़िगर करने की आवश्यकता है। यदि आप किसी भी 'if'/'else' का उपयोग करते हैं, तो यदि आप कोई है, तो आपके ऊपर निर्भर करता है, जब तक कि' getView() 'पर बहुत कॉल पर आप पूरी तरह से पंक्ति को कॉन्फ़िगर करते हैं। ओपी के मामले में, ओपी * कन्वर्टव्यू' 'शून्य 'नहीं होने पर पंक्ति को कॉन्फ़िगर नहीं कर रहा था। – CommonsWare

10
public View getView(int position, View convertView, ViewGroup parent) { 
    View view; 
    if (convertView == null) { 
     view= inflate your xml 
    } else { 
     view=convertView; 
    } 
    // all remaining code like 
    // view.findViewById(R.id.btn).setText("MyButton");        
    // must be outside if-else 
} 
1

मैं बस नष्ट कर दिया है

if(convertView==null) 

यह

0

मैं इस समाधान, एक और नमूने के आधार पर किया काम करता है, और काम किया:

public View getView(int position, View convertView, ViewGroup parent) { 
    View view = null; 
    if (convertView == null) { 
     view = inflate your xml and apply the View Holder pattern 
    } else { 
     view = convertView; 
    } 
    // retrieve the object by Holder pattern 
    // extra code here 
} 
1

अपने ग्रिड हैं आइटम में में कई दृश्य हैं आप getTag() और setTag() विधियों का उपयोग कर सकते हैं। इस मामले में, ग्रिड आइटम अब स्क्रॉलिंग पर अपने स्थान नहीं बदलेंगे और प्रदर्शन अभी भी ठीक होगा:

public class SomeAdapter extends BaseAdapter { 

    public static class ViewHolder { 
     public TextView tvTitle; 
     public ImageView imgPoster; 
    } 

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

     ViewHolder grid; 
     LayoutInflater inflator = activity.getLayoutInflater(); 

     if (convertView == null) { 
      grid = new ViewHolder(); 
      convertView = inflator.inflate(R.layout.grid_item, null); 
      grid.tvTitle = (TextView) convertView.findViewById(R.id.tv_title); 
      grid.imgPoster = (ImageView) convertView.findViewById(R.id.img_poster); 

      convertView.setTag(grid); // <<-- H E R E 
     } else { 
      grid = (ViewHolder) convertView.getTag(); // <<-- H E R E 
     } 
     grid.tvTitle.setText(dataItem.getTitle()); 
     grid.imgPoster.setImage(dataItem.getImage()); 
     return convertView; 
    } 
} 
संबंधित मुद्दे