5

Ich habe eine benutzerdefinierte Adapterimplementierung erstellt. Ich habe auch ein paar verschiedene Ansichtsarten in diesem Adapter.Dynamische Aktualisierung der Ansichtsarten von ListView

Ich muss einige Ansichten meines Adapters zur Laufzeit ersetzen. Romain Guy sagt, dass "... die Ansichtsart dynamisch geändert wird, was ein großer Fehler ist" (siehe ArrayAdapter and ListView - ArrayIndexOutOfBoundsException). Was ist die richtige Vorgehensweise, wenn sich die Anzahl der Ansichtsarten dynamisch ändert?

AdapterCode:

... 
private List<Class<?>> itemTypes = new ArrayList<Class<?>>(20); 

private void initList(List<Object> items) { 
    itemTypes = new ArrayList<Class<?>>(20); 
    positionSection = new SparseArray<Integer>(items.size()); 

    int count = 0; 
    int sectionIndex = -1; 
    for (Object object : items) { 
     Class<?> currentClass = object.getClass(); 
     if (object instanceof String) { 
      sectionIndex = count; 
     } 
     if (!itemTypes.contains(currentClass)) { 
      itemTypes.add(currentClass); 
     } 
     positionSection.put(count, sectionIndex); 
     count++; 
    } 
} 
@Override 
public int getItemViewType(int position) { 
    return itemTypes.indexOf(items.get(position).getClass()); 
} 

@Override 
public int getViewTypeCount() { 
    int size = itemTypes.size(); 
    return size == 0 ? 1 : size; 
} 

@Override 
public void notifyDataSetChanged() { 
    initList(items); 
    super.notifyDataSetChanged(); 
} 
... 

ich meine Artikeltyp Liste aktualisieren, nachdem ich meine Daten geändert haben, aber es funktioniert nicht wie beabsichtigt.

Die obigen Code führt zu einer ArrayIndexOutOfBounds Ausnahme:

10-21 20:18:16.231: E/AndroidRuntime(4475): java.lang.ArrayIndexOutOfBoundsException: length=3; index=3 
10-21 20:18:16.231: E/AndroidRuntime(4475):  at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:6437) 
10-21 20:18:16.231: E/AndroidRuntime(4475):  at android.widget.ListView.layoutChildren(ListView.java:1559) 
10-21 20:18:16.231: E/AndroidRuntime(4475):  at android.widget.AbsListView.onLayout(AbsListView.java:2102) 
10-21 20:18:16.231: E/AndroidRuntime(4475):  at se.davison.sodatools.widget.SectionListView.onLayout(SectionListView.java:147) 
10-21 20:18:16.231: E/AndroidRuntime(4475):  at android.view.View.layout(View.java:13754) 
10-21 20:18:16.231: E/AndroidRuntime(4475):  at android.view.ViewGroup.layout(ViewGroup.java:4362) 
+3

Sie können nicht den Wert von 'getViewTypeCount' ändern, da diese Methode nur einmal (wenn aufgerufen I bin nicht falsch) für den Adapter, aber Sie könnten dafür sorgen, dass ein Wert zurückgegeben wird, von dem Sie wissen, dass er der maximalen Anzahl von Typen entspricht, die der Adapter verwenden wird (z. B. 50). Aber ich würde mich mehr mit der Änderung der Zuordnung zwischen dem zurückgegebenen Typ und der Klasse befassen, auf die er in 'getItemViewType' zeigt, wenn sich die Reihenfolge in der 'itemTypes'-Liste ändert. – Luksprog

+0

Ah, das hat den Trick gemacht !!! ich danke dir sehr! – Richard

Antwort

1

mit Vorschlag Gelöst von https://stackoverflow.com/users/493939/luksprog

diese Methoden geändert und schaffen keine neue Instanz von itemTypes in initList

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

vom Benutzerprofil ?? – deadfish

+0

@deadfish Überprüfen Sie den Kommentar von Luksprog auf meine ursprüngliche Frage – Richard

-4

Ich denke, es gibt ein Problem hier:

@Override 
public int getViewTypeCount() 
{ 
    int size = itemTypes.size(); 
    return size == 0 ? 1 : size; 
} 

müssen Sie die Größe der Daten zu Ihrem Adapter bereitgestellt immer wieder zurückkehren

try folgende:

@Override 
public int getViewTypeCount() 
{ 
    int size = itemTypes.size(); 
    return size; 
} 
+2

Dies ist nicht wahr. Die Größe der Daten entspricht nicht der Größe meiner Ansichtstypen. – Richard