Updating ExpandableListView with notifyDataSetChanged()
Asked Answered
G

4

10

First a short overview of my code, i hope its understandable:

  • I have a class called ToDoElement with a few variables.
  • I have another class called ToDoListe which manages the ToDoElements in an ArrayList.
  • ToDoListe contains the method deleteElement() to delete a ToDoElement from the ArrayList
  • In my main activity liste_activity i create an object of ToDoListe and fill it with some Objects of ToDoElement.
  • In the same activity i have an ExpandableListView with my own Adapter called expListAdapter.
  • The Adapter creates the Groupviews and Childviews by getting the String variables of the ToDoElements.
  • I created a ContextMenu for every Group item of the list, in which i use the method deleteElement().

Ok, now here is my problem:

After i used the method deleteElement() i want to update my List, because the data of the ArrayList in ToDoListe changed. So i call expListAdapter.notifyDataSetChanged().
But then my whole activity crashes, with the reason: "IndexOutOfBoundException: Invalid index 4, size is 4" (I had 5 ToDoELement items in my list, before deleting one of them).
I know that's because of one of my for-loops, but i don't have any idea why.

Code fragments:

creating new Object of ToDoListe:

private static ToDoListe Liste = new ToDoListe();

class ToDoListe (just the important methods):

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

define list Adapter:

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

create ArrayLists for list 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;
}

my own List Adapter (just the important methods):

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

use of notifyDataSetChanged():

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


Thanks a lot for your attention!!

Gao answered 13/2, 2012 at 12:20 Comment(0)
P
6

You need to add a DeleteMethod of some sort to the Adapter and remove the item from the Adapter manually, not only remove it from the List.

Each time you refresh the the views using notifyDataSetChanged() the Adapter will call the loop around the List. Your List in the Adapter gets a null value due to the changes you made.

Pungent answered 13/2, 2012 at 12:44 Comment(3)
sounds good! can you give me an example, because i don't know how to write a Delete Method for an Adapter item.. ?Gao
ok, i figured it out, it works! Here is my code for the Delete Method in my ListAdapter: public void deleteItem (int nummer){ stichpunkte.remove(nummer); ueberschriften.remove(nummer); }Gao
and this is how i use it in my main activity: Liste.deleteElement(groupPos); expListAdapter.deleteItem(groupPos); expListAdapter.notifyDataSetChanged();Gao
S
5

Call super in your registerDataSetObserver meke notifyDataSetChanged() working well.

@Override
public void registerDataSetObserver(DataSetObserver observer) {
    super.registerDataSetObserver(observer);    
}
Sleepy answered 12/4, 2014 at 5:0 Comment(0)
A
2

You should call expListAdapter.notifyDataSetInvalidated()

expListAdapter.notifyDataSetChanged() will just update your views for the new values for each items (no change in any of the elements)

i.e it will again call your getChildView and getGroupView for each item.

Anthem answered 13/2, 2012 at 12:27 Comment(0)
H
0

In my case I was able to resolve this error by clearing the focus of the associated ExpandableListView before calling notifyDatasetChanged

Hagerman answered 24/5, 2021 at 18:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.