2010-06-02 4 views
36

Ich habe eine ListView in einem benutzerdefinierten ArrayAdapter, der ein Symbol ImageView und eine TextView in jeder Zeile anzeigt. Wenn ich die Liste lang genug mache, damit ich sie durchblättern kann, beginnt die Reihenfolge richtig, aber wenn ich mit dem Scrollen nach unten beginne, erscheinen einige der früheren Einträge wieder. Wenn ich zurück blättern gehe, ändert sich die alte Reihenfolge. Wenn Sie dies wiederholt ausführen, wird die gesamte Listenreihenfolge scheinbar zufällig. Wenn Sie also durch die Liste blättern, wird entweder die untergeordnete Reihenfolge geändert oder die Zeichnung wird nicht korrekt aktualisiert.ListView in ArrayAdapter Reihenfolge Get verwechselt beim Scrollen

Was könnte dazu führen, dass so etwas passiert? Ich brauche die Reihenfolge, in der die Elemente dem Benutzer angezeigt werden, um der Reihenfolge zu entsprechen, in der sie der ArrayList hinzugefügt werden, oder MINDESTENS, um in einer statischen Reihenfolge zu bleiben. Wenn ich detailliertere Informationen bereitstellen muss, lassen Sie es mich bitte wissen. Jede Hilfe wird geschätzt. Vielen Dank.

+1

Ich habe sehr lange Liste angezeigt werden, geschieht mit mir zu – Zoombie

Antwort

3

Die ListView verwendet beim Scrollen Ansichtsobjekte erneut. Überschreiben Sie die getView-Methode? Sie müssen sicherstellen, dass Sie jede Eigenschaft für jede Ansicht festlegen. Gehen Sie nicht davon aus, dass sie sich daran erinnert, was Sie zuvor hatten. Wenn Sie diese Methode posten, kann Sie jemand wahrscheinlich auf den Teil hinweisen, der falsch ist.

56

Ich hatte ähnliche Probleme, aber beim Klicken auf ein Element in der benutzerdefinierten Liste, würden die Elemente auf dem Bildschirm in der Reihenfolge umgekehrt werden. Wenn ich noch einmal klicke, kehren sie zurück zu ihrem Ursprung.

Nachdem ich dies gelesen hatte, überprüfte ich meinen Code, wo ich die getView-Methode überladen. Ich bekam die Ansicht von der konvertierten Ansicht, und wenn es null war, würde ich meine Sachen bauen. Nach dem Platzieren eines Haltepunkts stellte ich jedoch fest, dass diese Methode bei jedem Klick und bei nachfolgenden Klicks aufgerufen wurde. Die konvertierte Ansicht war nicht null, daher wurden die Elemente nicht festgelegt. Hier

ist ein Beispiel dafür, was es war:


public View getView(int position, View convertView, ViewGroup parent) 
{ 
    View view = convertView; 
    if (view == null) 
    { 
     LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     view = vi.inflate(R.layout.listitemrow, null); 

     RssItem rssItem = (RssItem) super.getItem(position); 
     if (rssItem != null) 
     { 
      TextView title = (TextView) view.findViewById(R.id.rowtitle); 
      if (title != null) 
      { 
       title.setText(rssItem.getTitle()); 
      } 
     } 
    } 
    return view; 
} 

Die subtile Veränderung auf der Ansicht, die enge Klammer für die Nullprüfung bewegt nur nach dem Aufblasen:


public View getView(int position, View convertView, ViewGroup parent) 
{ 
    View view = convertView; 
    if (view == null) 
    { 
     LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     view = vi.inflate(R.layout.listitemrow, null); 
    } 
    RssItem rssItem = (RssItem) super.getItem(position); 
    if (rssItem != null) 
    { 
     TextView title = (TextView) view.findViewById(R.id.rowtitle); 
     if (title != null) 
     { 
      title.setText(rssItem.getTitle()); 
     } 
    } 
    return view; 
} 

ich diese Hoffnung hilft anderen, die dasselbe Problem haben.

+1

Das ist die richtige Antwort. Ich wünschte, ich könnte es für dich akzeptieren. – Ian1971

+0

@farcrats es löste mein Problem auch ... +1 für diese Antwort ... – Dinash

+0

Das half mir auch. Danke für die klare Erklärung +1 – Sebs

4

weiter Um die Antwort von farcats unten in allgemeiner Art und Weise zu verdeutlichen, hier ist meine Erklärung:

Der vi.inflate Betrieb (hier für die Analyse des Layouts einer Reihe von XML benötigt und der Schaffung von das entsprechende View-Objekt) wird von einer if (view == null) Anweisung für Effizienz umhüllt, so dass das Aufblasen des gleichen Objekts nicht jedes Mal wieder geschieht, wenn es in Sicht kommt.

Die anderen Teile der getView-Methode werden jedoch verwendet, um andere Parameter festzulegen und sollten daher nicht in die if (view == null) Anweisung aufgenommen werden.

ähnlich, in anderer gemeinsamer Implementierung dieses Verfahrens, einige Textview, Image oder Imageelemente durch Werte aus der Liste [Position] aufgefüllt werden müssen, unter Verwendung von findViewById und danach .setText oder .setImageBitmap Operationen. Diese Operationen müssen nach sowohl Erstellen einer Ansicht von Grund auf durch Inflation und bekommen eine vorhandene Ansicht wenn nicht null.

Ein weiteres gutes Beispiel, wo diese Lösung für BaseAdapter angewandt wird, erscheint in BaseAdapter causing ListView to go out of order when scrolled

0

habe ich eine Listview, AdapterView und eine Ansicht (search_options), die EditText und 3 Spinner enthält. ListView-Elemente sind mehrere Kopien des Layouts (search_options), in denen der Benutzer weitere Optionen in ListView hinzufügen kann. Klicken Sie dann auf search, um die sql-Abfrage zu senden, die gemäß den Benutzeroptionen erstellt wurde.

Ich fand, dass convertView mischen indecies, so dass ich eine globale Liste (myViews) in Aktivität hinzugefügt und an ArrayAdapter übergeben. In ArrayAdapter (getView) füge ich dann jede neu hinzugefügte Ansicht hinzu (myViews).

Auch auf getView, anstatt zu überprüfen, ob convertView null ist, überprüfe ich, ob die globale Liste (myViews) eine Ansicht auf die ausgewählte (Position) hat. Es löste Probleme vollständig nach 3 Tagen Lesen des Internets !!

1- auf Aktivität hinzufügen dies:

Map<Integer, View> myViews = new HashMap<>(); 

und dann Adapter Konstruktor ArrayAdapter passieren.

mSOAdapter = new SearchOptionsAdapter(getActivity(), resultStrs, myViews); 

2- auf getView:

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

    View view; 
    ViewHolder viewHolder; 

    if (!myViews.containsKey(position)) { 
     viewHolder = new ViewHolder(); 
     LayoutInflater inflater = LayoutInflater.from(getContext()); 
     view = inflater.inflate(R.layout.search_options, parent, false); 

     /// ...... YOUR CODE 

     myViews.put(position, view); 

     FontUtils.setCustomFontsIn(view, getContext().getAssets()); 

    }else { 
     view = myViews.get(position); 
    } 

    return view; 
} 

schließlich nicht mehr Misch Artikel ...