home.

tagged: android-listview

Android: SimpleExpandableListAdapter example and tutorial

The SimpleExpandableListAdapter is not simple. It is, however, an ExpandableListAdapter.
 
Its nine argument constructor can be divided into three parts:

new SimpleExpandableListAdapter(
  this,
  
  groupData,
  android.R.layout.simple_expandable_list_item_1,
  new String[] { "ROOT_NAME" },
  new int[] { android.R.id.text1 },
  
  childData,
  android.R.layout.simple_expandable_list_item_2,
  new String[] { "CHILD_NAME", "CHILD_NAME" },
  new int[] { android.R.id.text1, android.R.id.text2 }
);

The first section is just the context. The second is the group data. The third is the child data. We'll look at the second section first.
 
Second section of parameters: group views
 
The groupData is a list of maps. Each map represents a row of the list:

List<Map<String, String>> groupData = new ArrayList<Map<String, String>>() {{
  add(new HashMap<String, String>() {{
  	put("ROOT_NAME", "Group 1");
  }});
  add(new HashMap<String, String>() {{
  	put("ROOT_NAME", "Group 2");
  }});
}};

So each Hashmap has a key "ROOT_NAME" with a value. This will be printed as the row name, as we will see below.
 
Let's look at the arguments again:

  ...
  groupData, // param 2
  android.R.layout.simple_expandable_list_item_1, // param 3
  new String[] { "ROOT_NAME" }, // param 4
  new int[] { android.R.id.text1 }, // param 5
  ...
  

So the groupData will have a list of maps. In those maps there'll be a value with the key ROOT_NAME (param 4). That value will be mapped to a android.R.id.text1 view id (param 5). That view must exist on android.R.layout.simple_expandable_list_item_1 (param 3).
 
Now we've done the group data. We'll do the child data:
 
Third section of parameters: child views
 
Again we have a list of maps, a childGroup. Each childGroup item will relate to a child element of a tier one row.
 
And so, we have to have a list of these childGroups. The first in the list of childGroups relates to a tier one row.

List<List<Map<String, String>>> listOfChildGroups = new ArrayList<List<Map<String, String>>>();

List<Map<String, String>> childGroupForFirstGroupRow = new ArrayList<Map<String, String>>(){{
  add(new HashMap<String, String>() {{
  	put("CHILD_NAME", "child in group 1");
  }});
  add(new HashMap<String, String>() {{
  	put("CHILD_NAME", "child in group 1");
  }});
}};
listOfChildGroups.add(childGroupForFirstGroupRow);

List<Map<String, String>> childGroupForSecondGroupRow = new ArrayList<Map<String, String>>(){{
  add(new HashMap<String, String>() {{
  	put("CHILD_NAME", "child in group 2");
  }});
  add(new HashMap<String, String>() {{
  	put("CHILD_NAME", "child in group 2");
  }});
}};
listOfChildGroups.add(childGroupForSecondGroupRow);

Now we have that datastructure we use it in the same way as we did for the group data:

            ...
            listOfChildGroups,
            android.R.layout.simple_expandable_list_item_2,
            new String[] { "CHILD_NAME", "CHILD_NAME" },
            new int[] { android.R.id.text1, android.R.id.text2 }
            ...
  

In each listOfChildGroups item, there's a map. That map has a key called CHILD_NAME. The value for that is given to the TextView referenced by android.R.id.text1 and both android.R.id.text2. Those textviews exist on the android.R.layout.simple_expandable_list_item_2,.
 
And now:

  	expandableListView.setAdapter(thatHorrificSimpleExpandableListAdapter);

Apparently extending the BaseExpandableListAdapter is seen as a better option most of the time.

android android-listview

Page 1 of 1