2010-06-26 4 views
7

Ich habe eine dynamische ListView, die ein ArrayAdapter verwendet. Wenn ein Name aus einem Drehfeld ausgewählt wird, wird der Name zusammen mit einem Symbol, das angibt, ob es männlich oder weiblich ist, zu ListView hinzugefügt.Listview mit ArrayAdapter und ViewHolder Symbole an den falschen Artikel Hinzufügen

Meistens ist alles gut (der Name richtig in die Liste aufgenommen wird, zusammen mit einem Symbol). Aber das Symbol, das den Sex zeigt, wird dem falschen Gegenstand im ListView hinzugefügt. Der Name wird am Ende der Liste hinzugefügt, das Symbol wird jedoch an den Namen oben in der Liste gesetzt. Ich weiß nicht, ob es die Möglichkeit gibt, ich bin ViewHolder verwenden, aber es gibt null Dokumentation in den Android website.

// Listview inflater 
inflater = (LayoutInflater) (this).getSystemService(LAYOUT_INFLATER_SERVICE); 

// List Array. 
mAdapter = new ArrayAdapter<String>(this, R.layout.player_simple_list, 
               R.id.label, mStrings) { 

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

     Log.i("ANDY","View getView Called"); 
     // A ViewHolder keeps references to children views to 
     // avoid unneccessary calls to findViewById() on each row. 
     ViewHolder holder; 

     if (null == convertView) { 
      Log.i("ANDY","Position not previously used, so inflating"); 
      convertView = inflater.inflate(R.layout.player_simple_list, null); 
      // Creates a ViewHolder and store references to the 
      // two children views we want to bind data to. 
      holder = new ViewHolder(); 
      holder.text = (TextView) convertView.findViewById(R.id.label); 
      holder.icon = (ImageView) convertView.findViewById(R.id.icon); 
      if (sexmale == true) { 
       holder.icon.setImageBitmap(maleicon); 
      } 
      else { 
       holder.icon.setImageBitmap(femaleicon); 
      } 
      convertView.setTag(holder); 
     } else { 
      // Get the ViewHolder back to get fast access to the TextView 
      // and the ImageView. 
      holder = (ViewHolder) convertView.getTag(); 

     } 
     // Bind the data efficiently with the holder. 
     holder.text.setText(getItem(position)); 
     // Change icon depending is the sexmale variable is true or false. 
     Log.i("ANDY","getCount = "+mAdapter.getCount()); 
     return convertView; 
    } 
}; 
setListAdapter(mAdapter); 
+0

Es gibt einige faire Dokumentation gibt: https://developer.android.com/training/improving-layouts/smooth-scrolling.html – Vince

Antwort

1

Update:ViewHolder soll nur Verweise auf die Komponente Blick in das Element Layout halten. Dies hilft, den Aufwand des Aufrufs findViewById zum Rendern der einzelnen Komponenten innerhalb komplexen Artikel Layouts mit mehreren Komponenten (wie die TextView und ImageView in diesem Fall) zu vermeiden.

Ich reparierte es, indem ich eine Routine (genannt getSex) verwendete, um die Geschlechtsdaten abzurufen und alle Ansichtdaten einschließlich Ikonen außerhalb der if-else Blöcke einzustellen.

Der Arbeits Code sieht nun wie folgt aus:

if (null == convertView) { 
    Log.i("ANDY","Position not previously used, so inflating"); 
    convertView = inflater.inflate(R.layout.player_simple_list, null); 

    // Creates a ViewHolder and store references to the two children views 
    // we want to bind data to. 
    holder = new ViewHolder(); 
    holder.text = (TextView) convertView.findViewById(R.id.label); 
    holder.icon = (ImageView) convertView.findViewById(R.id.icon); 
    convertView.setTag(holder); 
} else { 
    // Get the ViewHolder back to get fast access to the TextView 
    // and the ImageView. 
    holder = (ViewHolder) convertView.getTag(); 
} 

// Bind the data efficiently with the holder. 
holder.text.setText(getItem(position)); 
// Change icon depending is the sexmale variable is true or false. 
if (getSex (getItem(position)) == true) { 
    holder.icon.setImageBitmap(maleicon); 
} 
else { 
    holder.icon.setImageBitmap(femaleicon); 
} 
return convertView; 
1

Sie haben von den, wenn ein paar Zeilen von Daten nach dem Kommentar zu bewegen, wie in diesem question is explained

// Bind the data efficiently with the holder. 

so wird es diese aussehen

if (null == convertView) { 
    Log.i("ANDY","Position not previously used, so inflating"); 
    convertView = inflater.inflate(R.layout.player_simple_list, null); 
    // Creates a ViewHolder and store references to the two children views 
    // we want to bind data to. 
    holder = new ViewHolder(); 
    convertView.setTag(holder); 
} else { 
    // Get the ViewHolder back to get fast access to the TextView 
    // and the ImageView. 
    holder = (ViewHolder) convertView.getTag(); 
} 

// Bind the data efficiently with the holder. 
holder.text = (TextView) convertView.findViewById(R.id.label); 
holder.icon = (ImageView) convertView.findViewById(R.id.icon); 
if (sexmale == true) { 
    holder.icon.setImageBitmap(maleicon); 
} 
else { 
    holder.icon.setImageBitmap(femaleicon); 
} 
holder.text.setText(getItem(position)); 
+3

ich nicht einverstanden sind, Dies macht den 'ViewHolder' einfach nutzlos, da Sie ihn jedes Mal überschreiben. Die richtige Lösung sollte 'holder.text' und' holder.icon' im 'if'-Zweig setzen und den Inhalt (' setText', 'setImageBitmap') außerhalb des' if'-Blocks setzen. – cristis

+0

Ich denke, das Überschreiben muss da sein, denn wenn nicht, wird es Daten in Bezug auf eine andere Aufzeichnungsposition enthalten. Zum Beispiel zeigen Sie Datensatz 10, und wenn die Cache-Ansicht von Datensatz 3, wiederverwenden, wenn Sie die Daten nicht für Datensatz 3 gesetzt überschrieben wird für die Aufzeichnung 10. – Pentium10

+1

@ Pentium10 sichtbar sein: nein, Cristis ist richtig. Der 'ViewHolder' ist an die Zeile gebunden, also ändert sich nicht, welche Widgets er enthält. Was sich einfach ändern muss, ist der Inhalt dieser Widgets. – CommonsWare

2

Sie müssen Stellen Sie die Symbole nach if-else-if zum Erstellen oder Binden eines holder. Andernfalls würden die Symbole nur in den ersten wenigen Punkten in der Liste richtig angezeigt werden, d. H. Bis die ListView nicht gefüllt ist.

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

    Log.i("ANDY","View getView Called"); 
    // A ViewHolder keeps references to children views 
    // to avoid unneccessary calls to findViewById() on each row. 
    ViewHolder holder; 

     if (null == convertView) { 
      Log.i("ANDY","Position not previously used, so inflating"); 
      convertView = inflater.inflate(R.layout.player_simple_list, null); 

      // Creates a ViewHolder and store references to 
      // the two children views we want to bind data to. 
      holder = new ViewHolder(); 
      holder.text = (TextView) convertView.findViewById(R.id.label); 
      holder.icon = (ImageView) convertView.findViewById(R.id.icon); 
      convertView.setTag(holder); 
     } else { 
      // Get the ViewHolder back to get fast access to the TextView 
      // and the ImageView. 
      holder = (ViewHolder) convertView.getTag(); 

     } 
     // Bind the data efficiently with the holder. 
     holder.text.setText(getItem(position)); 

     // Change icon depending is the sexmale variable is true or false. 
     if (sexmale == true) { 
      holder.icon.setImageBitmap(maleicon); 
     } 
     else { 
      holder.icon.setImageBitmap(femaleicon); 
     } 
     Log.i("ANDY","getCount = "+mAdapter.getCount()); 
     return convertView; 
} 
+0

Hallo. Ich habe das versucht, aber alle Symbole ändern sich in den gleichen Typ, alle auf der Liste. Wenn ein männlicher Name ausgewählt wird, werden alle Symbole männlich. –