2012-02-13 5 views
8

Pierwszy krótki przegląd mojego kodu, mam nadzieję, że jej zrozumiałe:Aktualizacja ExpandableListView z notifyDataSetChanged()

  • Mam klasy o nazwie ToDoElement z kilku zmiennych.
  • Mam inną klasę o nazwie ToDoListe, która zarządza ToDoElement s w ArrayList.
  • ToDoListe zawiera metodę deleteElement() aby usunąć ToDoElement z ArrayList
  • W moim głównym działalności liste_activity i utworzyć obiekt ToDoListe i wypełnić go z niektórych obiektów ToDoElement.
  • W tej samej działalności mam ExpandableListView z własnym adapterem o nazwie expListAdapter.
  • Adapter tworzy widoki grupowe i potomne, pobierając zmienne String z ToDoElement.
  • Utworzyłem ContextMenu dla każdego elementu grupy z listy, w którym używam metody deleteElement().

Ok, oto mój problemem:

Po użyłem metody deleteElement() chcę zaktualizować listy, ponieważ dane ArrayList w ToDoListe zmieniło. Więc nazywam się expListAdapter.notifyDataSetChanged().
Ale wtedy cała moja działalność ulega awarii, z powodu: "IndexOutOfBoundException: Invalid index 4, size is 4" (Miałem 5 ToDoELement pozycji na mojej liście, przed skasowaniem jednego z nich).
Wiem, że to z powodu jednej z moich pętli for, ale nie mam pojęcia, dlaczego.

fragmenty kodu:

tworząc nowy obiekt ToDoListe:

private static ToDoListe Liste = new ToDoListe(); 

klasy ToDoListe (tylko ważne metody):

public class ToDoListe { 

    private ArrayList<ToDoElement> ToDoListe; 

    public ToDoListe() 
    { 
     ToDoListe = new ArrayList<ToDoElement>(); 
    } 

    public void newElement(ToDoElement element){ 
     ToDoListe.add(element); 
    } 

    public void deleteElement(int nummer) { 
     ToDoListe.remove(nummer); 
    } 

    public int AnzahlElemente() { 
     return ToDoListe.size(); 
    } 
} 

zdefiniowanie listy Adapter:

expListAdapter = new MyListAdapter(this, createGroupList(), createChildList()); 
setListAdapter(expListAdapter); 

tworzyć ArrayLists do listy Adapter:

// creates the list with the group items 
private List createGroupList() { 
     ArrayList result = new ArrayList(); 
     for (int i=0; i < Liste.AnzahlElemente(); i++) { 
     result.add(Liste.getElement(i).getUeberschrift()); 
     } 
     return result; 
    } 

// creates the list with the child items 
private List createChildList() { 
     ArrayList result = new ArrayList(); 
     for(int i=0; i < Liste.AnzahlElemente(); i++) { 
      ArrayList secList = new ArrayList(); 
      for(int n = 1 ; n <= 3 ; n++) { 
       if (Liste.getElement(i).getStichpunkt(n).length() != 0){ 
        secList.add("- " + Liste.getElement(i).getStichpunkt(n)); 
       } 
      } 
      result.add(secList); 
     } 
     return result; 
} 

własnej listy Adapter (tak ważnych metod):

public class MyListAdapter extends BaseExpandableListAdapter{ 

private ArrayList<String> ueberschriften; 
private ArrayList<ArrayList<String>> stichpunkte; 

private LayoutInflater inflater; 


public MyListAdapter(Context context, List _ueberschriften, List _stichpunkte) { 

     this.ueberschriften = (ArrayList)_ueberschriften; 
     this.stichpunkte = (ArrayList)_stichpunkte; 

     inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     } 

public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { 

     if (convertView == null) { 
      convertView = inflater.inflate(R.layout.item_child, null); 
     } 
     TextView tv = (TextView) convertView.findViewById(R.id.item_child_title); 
     tv.setText(liste_activity.getListe().getElement(groupPosition).getStichpunkt(childPosition)); 

     return convertView; 
    } 

public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { 

    if (convertView == null) { 
     convertView = inflater.inflate(R.layout.item_group, null); 
    } 

    TextView tv = (TextView)convertView.findViewById(R.id.item_group_title); 
    tv.setText(liste_activity.getListe().getElement(groupPosition).getUeberschrift()); 

    return convertView; 
} 

wykorzystanie notifyDataSetChanged():

Liste.deleteElement(groupPos); 
expListAdapter.notifyDataSetChanged(); 


Wielkie dzięki za uwagę!

Odpowiedz

4

Trzeba dodać DeleteMethod jakiegoś do Adapter i usunąć element z Adapter ręcznie, nie tylko usunąć go z List.

Za każdym razem, gdy odświeżasz widoki za pomocą notifyDataSetChanged(), Adapter wywoła pętlę wokół List. Twoja List w Adapter otrzymuje wartość pustą ze względu na wprowadzone zmiany.

+0

brzmi dobrze! czy możesz podać mi przykład, ponieważ nie wiem, jak napisać metodę usuwania elementu adaptera ..? – OnClickListener

+0

ok, zorientowałem się, to działa! Tu jest mój kodu dla metody Delete w moim ListAdapter: \t 'void deleteItem (int) {nummer' \t \t 'stichpunkte.remove (nummer);' \t \t 'ueberschriften.remove (nummer),' \t '}' – OnClickListener

+0

i tak używam go w mojej głównej działalności: 'Liste.deleteElement (groupPos);' 'expListAdapter.deleteItem (groupPos);' 'expListAdapter.notifyDataSetChanged();' – OnClickListener

0

Należy zadzwonić expListAdapter.notifyDataSetInvalidated()

expListAdapter.notifyDataSetChanged() po prostu zaktualizować widoki dla nowych wartości dla każdej pozycji (bez zmian w którymkolwiek z elementów)

czyli będzie ponownie połączyć się getChildView i getGroupView dla każdej pozycji .

+0

dzięki! ale nadal zawiesza się z tym samym komunikatem o błędzie! – OnClickListener

4

Wywołanie super w rejestrzeDataSetObserver meke notifyDataSetChanged() działa dobrze.

@Override 
public void registerDataSetObserver(DataSetObserver observer) { 
    super.registerDataSetObserver(observer);  
}