添加数据时刷新ExpandableListView:保持状态

时间:2013-02-25 10:18:29

标签: android expandablelistview

我使用ExpandableListView使用自定义适配器填充BaseExpandableListAdapter。我可以在新活动中添加新数据,然后我必须刷新列表。刷新列表时,我想保持扩展相同的组。

可以在列表中的任何位置添加新条目。我们可以添加新组或只是新孩子。

现在我正在使用:

adapter.notifyDataSetChanged();

列表刷新,但状态不一样。例如,如果我有三个组:G1扩展,G2未扩展,G3扩展,我在G2和G3之间添加一个新组G4,然后G4获得G3状态,因为它占据了它的位置。有没有办法自动保持状态,或者我必须在我的适配器中手动完成?

谢谢!

[编辑]

添加一些代码。

这是我的适配器:

public class StopsInnerExpandableListAdapter extends BaseExpandableListAdapter {

private ArrayList<String> groups; // Dates.
private ArrayList<ArrayList<HashMap<String, String>>> children; // HashMap has stop ID, image and price.
private Context context;

public StopsInnerExpandableListAdapter (Context ctx, ArrayList<String> groups, 
        ArrayList<ArrayList<HashMap<String, String>>> children) {
    context = ctx;
    this.groups = groups;
    this.children = children;
}

@Override
public boolean areAllItemsEnabled() {
    return true;
}

public HashMap<String, String> getChild(int groupPosition, int childPosition) {
    return children.get(groupPosition).get(childPosition);
}

public long getChildId(int groupPosition, int childPosition) {
    return childPosition;
}

public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    if (convertView == null) {
        // Inflate child's view.
        LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.stop_row, null);
    }

    // Get the stop data and use it to fill the child's views.
    HashMap<String, String> child = children.get(groupPosition).get(childPosition);

    ...

    return convertView;
}

public int getChildrenCount(int groupPosition) {
    return children.get(groupPosition).size();
}

public String getGroup(int groupPosition) {
    return groups.get(groupPosition);
}

public int getGroupCount() {
    return groups.size();
}

public long getGroupId(int groupPosition) {
    return groupPosition;
}

public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { 
    if (convertView == null) {
        // Inflate group's view.
        LayoutInflater infalInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.stop_subgroup, null);
    }

    String date = groups.get(groupPosition);

    TextView dateView = (TextView) convertView.findViewById(R.id.title_date);
    dateView.setText(date);

    return convertView;
}

public boolean hasStableIds() {
    return true;
}

public boolean isChildSelectable(int arg0, int arg1) {
    return true;
}

public void updateData(ArrayList<String> groups,
        ArrayList<ArrayList<HashMap<String, String>>> children) {
    this.groups = groups;
    this.children = children;
}
}

在我的活动中,我这样做:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.stop_list);

    mExpandableList = (ExpandableListView)findViewById(R.id.expandable_list);

    model = new MyModel(this);
}

@Override
protected void onResume() {
    super.onResume();

    ListEntries entries = model.getEntries();

    if(adapter == null){
        // Sets the adapter that provides data to the list.
        adapter = new StopsInnerExpandableListAdapter(this, entries.getDates(), entries.getChilds());
        mExpandableList.setAdapter(adapter);
    }
    else{
        adapter.updateData(entries.getDates(), entries.getChilds());
        adapter.notifyDataSetChanged();
    }

}

1 个答案:

答案 0 :(得分:2)

ExpandableListView未正确重新展开,因为您没有使用稳定的ID。使用稳定的ID将为您解决问题。

虽然您通过此处启用了稳定ID:

public boolean hasStableIds() {
    return true;
}

您仍需要使用getGroupId()getChildId()方法实际返回稳定ID。分别返回groupPositionchildPosition不符合稳定ID。

要成为稳定的ID意味着返回的值在整个数据集中都是唯一的。此外,无论给定项目的位置如何,返回的值都是相同的。例如,假设您正在存储人员。每个人都有一个独特的SSN。这将是一个很好的稳定ID,可以getChildId()返回。例如,如果约翰史密斯位于第2,4位(组,子),然后稍后移动到位置(3,1)......他的稳定ID(或SSN)仍将是相同的。仅返回位置编号不能保证这一点。