2012-02-13 29 views
8

Đầu tiên một đoạn ngắn tổng quan mã của tôi, tôi hy vọng có thể hiểu nó:Đang cập nhật ExpandableListView với notifyDataSetChanged()

  • Tôi có một lớp được gọi là ToDoElement với một vài biến.
  • Tôi có một lớp khác được gọi là ToDoListe quản lý số ToDoElement trong một ArrayList.
  • ToDoListe chứa các phương pháp deleteElement() để xóa một ToDoElement từ ArrayList
  • Trong hoạt động chính của tôi liste_activity tôi tạo ra một đối tượng của ToDoListe và điền nó với một số đối tượng của ToDoElement.
  • Trong cùng một hoạt động, tôi có một ExpandableListView với Bộ điều hợp riêng của mình có tên là expListAdapter.
  • Bộ điều hợp tạo Nhóm xem và Đánh giá trẻ em bằng cách nhận các biến Chuỗi của ToDoElement s.
  • Tôi đã tạo một ContextMenu cho mọi mục Nhóm trong danh sách, trong đó tôi sử dụng phương thức deleteElement().

Ok, bây giờ ở đây là tôi vấn đề:

Sau khi tôi sử dụng phương pháp deleteElement() tôi muốn cập nhật Danh sách của tôi, vì dữ liệu của ArrayList trong ToDoListe thay đổi. Vì vậy, tôi gọi expListAdapter.notifyDataSetChanged().
Nhưng sau đó toàn bộ hoạt động của tôi bị lỗi, với lý do: "IndexOutOfBoundException: Chỉ mục 4 không hợp lệ, kích thước là 4" (Tôi có 5 ToDoELement mục trong danh sách của mình trước khi xóa một trong số chúng).
Tôi biết đó là vì một trong những vòng lặp của tôi, nhưng tôi không biết tại sao.

mảnh Code:

tạo Object mới của ToDoListe:

private static ToDoListe Liste = new ToDoListe(); 

lớp ToDoListe (chỉ là phương pháp quan trọng):

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

xác định danh sách Adaptor:

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

tạo ArrayLists cho danh sách Adaptor:

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

riêng Danh sách Adaptor của tôi (chỉ là phương pháp quan trọng):

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

sử dụng notifyDataSetChanged():

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


Cảm ơn bạn rất nhiều vì đã chú ý !!

Trả lời

4

Bạn cần phải thêm một DeleteMethod của một số loại đến Adapter và loại bỏ các mục từ Adapter bằng tay, không chỉ loại bỏ nó ra khỏi List.

Mỗi khi bạn làm mới các chế độ xem bằng cách sử dụng notifyDataSetChanged(), Adapter sẽ gọi vòng lặp xung quanh List. Số List của bạn trong số Adapter nhận giá trị null do những thay đổi bạn đã thực hiện.

+0

nghe hay đấy! bạn có thể cho tôi một ví dụ, bởi vì tôi không biết làm thế nào để viết một phương pháp xóa cho một mục Adapter ..? – OnClickListener

+0

ok, tôi đã tìm ra, nó hoạt động! Đây là mã của tôi cho Phương Xóa trong ListAdapter tôi: \t 'public void deleteItem (int nummer) {' \t \t 'stichpunkte.remove (nummer); ' \t \t' ueberschriften.remove (nummer);' \t '}' – OnClickListener

+0

và đây là cách tôi sử dụng nó trong hoạt động chính của mình: 'Liste.deleteElement (groupPos);' 'expListAdapter.deleteItem (groupPos);' 'expListAdapter.notifyDataSetChanged();' – OnClickListener

0

Bạn nên gọi expListAdapter.notifyDataSetInvalidated()

expListAdapter.notifyDataSetChanged() sẽ chỉ cập nhật điểm của bạn cho các giá trị mới cho mỗi mặt hàng (không thay đổi trong bất kỳ các yếu tố)

tức là nó sẽ một lần nữa gọi getChildView của bạn và getGroupView cho từng hạng mục .

+0

cảm ơn! nhưng nó vẫn bị treo với cùng một thông báo lỗi! – OnClickListener

4

Gọi siêu trong sổ đăng ký của bạnDataSetObserver meke thông báoDataSetChanged() hoạt động tốt.

@Override 
public void registerDataSetObserver(DataSetObserver observer) { 
    super.registerDataSetObserver(observer);  
} 
Các vấn đề liên quan