2016-03-19 11 views
0

Ich weiß, dass dies ein sehr häufiges Problem bei der Verwendung von ListView ist. Allerdings konnte ich mit meiner Implementierung nichts falsch finden, da ich das ViewHolder-Muster für meinen benutzerdefinierten Adapter richtig befolgt habe.Android ListView: Änderungen an Elementen beeinflussen andere Elemente

Das Problem:

Änderungen an einem Artikel, wie zum Beispiel das Textview-Text in einer Zeit verändert wirkt sich auf andere zufällige Elemente, wenn/oben nach unten gescrollt. Wenn ich zurück scrolle, wird das ursprüngliche Element sowie andere Elemente geändert. Dieses Problem kann mit einem ViewHolder Muster behoben werden. Es ist seltsam, weil ich immer noch das Problem habe!

Adapter Code:

public class TrackerAdapter extends BaseAdapter { 
    private Activity activity; 
    private static LayoutInflater inflater = null; 
    ArrayList <Set> sets = new ArrayList <>(); 

    public TrackerAdapter(Activity a, final ArrayList <Set> sets) { 
     this.activity = a; 
     this.inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     this.sets = sets; 
    } 

    public int getCount() { 
     return sets.size(); 
    } 
    public Set getItem(int position) { 
     return sets.get(position); 
    } 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public int getViewTypeCount() { 
     return 1; 
    } 

    @Override 
    public int getItemViewType(int position) { 
     return position; 
    } 

    public View getView(final int position, View convertView, ViewGroup parent) { 
     View view = convertView; 
     final Set set = sets.get(position); 
     final Holder holder; 
     try { 
      if (view == null) { 
       view = inflater.inflate(R.layout.row_single, null); 
       holder = new Holder(); 
       holder.name = (TextView) view.findViewById(R.id.name); 
       view.setTag(holder); 
      } else { 
       holder = (Holder) view.getTag(); 
      } 
      holder.name.setText(set.getUser().getName()); 
     } catch (Exception ex) { 
      Log.d("CHECK", "Error at TrackerAdapter"); 
      Log.d("CHECK", Log.getStackTraceString(ex)); 
     } 
     return view; 
    } 
    public static class Holder { 
     TextView name; 
    } 
} 

Welche Frage haben Sie in meinem Code zu sehen? Habe ich das ViewHolder-Muster richtig implementiert?

Antwort

0

Ihr Code sieht richtig aus, also werde ich eine wilde Vermutung nehmen und sagen, dass Sie die Unterstützung ArrayList von außen geändert haben. Sie können das nicht tun, ohne die ListView nach einer Änderung zu benachrichtigen.

Der folgende Code wird Ihr funktionierendes Array und die angezeigten Daten entkoppeln.

final ArrayList <Set> sets = new ArrayList <>(); 

public TrackerAdapter() { 
} 

public void setItems(ArrayList<Set> sets) { 
    this.sets.clear(); 
    this.sets.addAll(sets) 
    notifyDataSetChanged(); 
} 

public View getView(final int position, View convertView, ViewGroup parent) { 
    View view = convertView; 
    final Set set = sets.get(position); 
    final Holder holder; 

    if (view == null) { 
     Context context = parent.getContext(); 
     LayoutInflater inflater = LayoutInflater.from(context); 
     view = inflater.inflate(R.layout.row_single, parent, false); 
     holder = new Holder(); 
     holder.name = (TextView) view.findViewById(R.id.name); 
     view.setTag(holder); 
    } else { 
     holder = (Holder) view.getTag(); 
    } 

    holder.name.setText(set.getUser().getName()); 

    return view; 
} 
+0

Danke für die Antwort! :) Ich bin ein bisschen verwirrt obwohl.Was ist setItems und wann heißt es?Warum haben Sie auch den Konstruktor ausgeleert? – Dinuka

+0

** 1) ** Rufen Sie 'setItems' auf, wenn Sie Änderungen am Datensatz vornehmen. Dazu gehört das Hinzufügen von Objekten, das Entfernen von Objekten, das Ändern von Objekten und das Verschieben von Objekten. ** 2) ** Der Konstruktor ist leer, weil ich dort nichts brauche. Ich erhalte einen 'LayoutInflater', wenn ich ihn von' ListView' (Eltern) brauche, was themenbezogene Probleme vermeiden sollte (imagine activity hatte ein anderes Thema als die Listenansicht). –

-1

Array Adapter

Holder holder = new Holder(); 
if (convertView == null) { 
    convertView = inflater.inflate(R.layout.row_single, null); 
    holder.name = (TextView) view.findViewById(R.id.name); 
    convertView.setTag(holder); 
} else { 
    holder = (Holder) convertView.getTag(); 
} 
holder.set = getItem(position); 
holder.name.setText(holder.set.getUser().getName()); 
public static class Holder { 
    TextView name; 
    Set set; 
} 

Durch die Verwendung von Basis Adapter

Holder holder = new Holder(); 
if (convertView == null) { 
    convertView = inflater.inflate(R.layout.row_single, null); 
    holder.name = (TextView) view.findViewById(R.id.name); 
    convertView.setTag(holder); 
} else { 
    holder = (Holder) convertView.getTag(); 
} 
holder.name.setText(sets.get(position).getName()); 
public static class Holder { 
    TextView name; 
} 
+0

Können Sie erklären, was Sie hier geändert haben? – Dinuka

+0

Ja sicher .. Ich entfernte das endgültige Schlüsselwort und bekomme Wert in der Arraylist mit der Hilfe Position – user6085773

+0

Ich benutze den BaseAdapter aber kein Glück Mate. Erhalten Sie immer noch das Problem – Dinuka

0

Was ist so, wie Sie Ihren Textview Text ändern Durch den Einsatz? Direkt in TextView selbst oder in dem entsprechenden Element von ArrayList, und dann nur adapter.notifyDataSetChanged()?

Und eine seltsame Sache. getViewTypeCount() gibt die Anzahl der XMLs zurück, die Sie in der Liste auffüllen möchten. Wenn Sie nur 1 xml haben, ist return 1 in Ordnung (aber, wie für mich, wenn es 1 ist, schreibe diese Methode explizit redundant). Aber in getItemViewType() sollten Sie Bedingungen schreiben, abhängig davon, welches Element den einen oder anderen viewType bekommt. Und Sie geben die aktuelle Position zurück, besser beheben Sie es :)

+0

Ich ändere die Textansicht in der Zeile: 'Halter .name.setText (set.getUser(). getName()); ' im Inneren des Adapters – Dinuka

Verwandte Themen