Update ExpandableListView when adding data: save state

I have an ExpandableListView populated using a custom adapter using a BaseExpandableListAdapter . I can add new data to a new action, and then I need to update the list. When the list is updated, I want the same groups to expand.

New entries can be added anywhere in the list. We can add new groups or only new children.

Now I am using:

 adapter.notifyDataSetChanged(); 

The list is updated, but the status does not match. In the example, if I have three groups: G1 is expanded, G2 is not expanded, G3 is expanded, and I add a new group G4 between G2 and G3, then G4 gets the state G3, since it takes its position. Is there a way to save state automatically or do I need to do this manually in my adapter?

Thanks!

[EDIT]

Adding some code.

This is my adapter:

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

In my activity I do this:

 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(); } } 
+4
source share
1 answer

ExpandableListView not redistributed correctly because you are not using stable identifiers. Using stable identifiers will help you solve this problem.

So far you have included stable identifiers:

 public boolean hasStableIds() { return true; } 

You still need to return stable identifiers using the getGroupId() and getChildId() methods. The return of groupPosition and childPosition respectively, is not among the stable identifiers.

To be stable, an identifier means that the return value will be unique to the entire dataset. In addition, the return value will be the same no matter what the position of this element is. For example, let's say you keep people. Each person has a unique SSN. This would be a great stable id to return with getChildId() . For example, if John Smith is in position 2, 4 (group, child), and then moves to position (3, 1) ... his stable identifier (or SSN) will still match. Returning only item numbers cannot guarantee this.

+2
source

All Articles