2012-02-13 20 views
8

En primer lugar una breve visión general de mi código, espero que sea comprensible:ExpandableListView Actualizando con notifyDataSetChanged()

  • tengo una clase llamada ToDoElement con unas pocas variables.
  • Tengo otra clase llamada ToDoListe que gestiona el ToDoElement s en una ArrayList.
  • ToDoListe contiene el método para eliminar un deleteElement()ToDoElement del ArrayList
  • En mi actividad liste_activity i crear un objeto de ToDoListe y llenarlo con algunos objetos de ToDoElement.
  • En la misma actividad tengo un ExpandableListView con mi propio adaptador llamado expListAdapter.
  • El adaptador crea las vistas de grupo y las vistas de niños al obtener las variables de cadena de ToDoElement s.
  • Creé un ContextMenu para cada elemento de grupo de la lista, en el que utilizo el método deleteElement().

Ok, ahora aquí está mi problema :

después de utilizar el método deleteElement() quiero actualizar mi lista, porque los datos del ArrayList en ToDoListe cambiaron. Entonces llamo al expListAdapter.notifyDataSetChanged().
Pero luego toda mi actividad falla, con el motivo: "IndexOutOfBoundException: Índice inválido 4, tamaño es 4" (tuve 5 ToDoELement elementos en mi lista, antes de eliminar uno de ellos).
Sé que es por uno de mis for-loops, pero no tengo ni idea de por qué.

fragmentos de código:

que creen nuevo objeto de ToDoListe:

private static ToDoListe Liste = new ToDoListe(); 

ToDoListe clase (sólo los métodos importantes):

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(); 
    } 
} 

definir adaptador lista:

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

crear ArrayLists para el adaptador de la lista:

// 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; 
} 

mi propio adaptador de la lista (sólo los métodos importantes):

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; 
} 

uso de notifyDataSetChanged():

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


¡Muchas gracias por su atención!

Respuesta

4

es necesario agregar un DeleteMethod de algún tipo para la Adapter y quitar el elemento de la Adapter manualmente, no sólo sacarlo de la List.

Cada vez que se actualizan las vistas utilizando los notifyDataSetChanged() la Adapter llamará al bucle alrededor de la List. Su List en el Adapter obtiene un valor nulo debido a los cambios que ha realizado.

+0

suena bien! ¿Me puede dar un ejemplo, porque no sé cómo escribir un Método de eliminación para un elemento Adaptador ...? – OnClickListener

+0

bien, lo descubrí, ¡funciona! Aquí está mi código para el método Delete en mi ListAdapter: \t 'public void deleteItem (int Nummer) {' ' \t \t stichpunkte.remove (nummer);' ' \t \t ueberschriften.remove (nummer);' \t '}' – OnClickListener

+0

y así es como lo uso en mi actividad principal: 'Liste.deleteElement (groupPos);' 'expListAdapter.deleteItem (groupPos);' 'expListAdapter.notifyDataSetChanged();' – OnClickListener

0

Debe llamar expListAdapter.notifyDataSetInvalidated()

expListAdapter.notifyDataSetChanged() se acaba de actualizar su punto de vista de los nuevos valores para cada uno de los elementos (no hay cambio en cualquiera de los elementos)

es decir, que volverá a llamar a su getChildView y getGroupView para cada elemento .

+0

gracias! ¡pero todavía se bloquea con el mismo mensaje de error! – OnClickListener

4

Llamar súper en su registerDataSetObserver meke notifyDataSetChanged() funciona bien.

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