Using SimpleExpandableListAdapter

I recently needed to modify one of my apps to change the way I display a list of things with dates from a flat ListView to an ExpandableListView, grouped by day. The items displayed are backed by  a SQLite database which we use ORMLite to interface with. The ListView was already using a custom adapter that extended an ArrayAdapter and supported actions like Delete and Edit on long press. I needed to provide the exact same functionality in an ExpandableListView.

Initially it seemed like a trivial change; Android already provided a SimpleExpandableListAdapter. However, the constructor alone would scare the average developer (myself included) into looking for another option. Other solutions work well with Cursors, but we had abstracted them out with our use of an ORM. So I was committed to the SimpleExpandableListAdapter, which, after closer inspection, is actually not that bad. After converting the ListView tag in my layout to an ExpandableListView and extending my Activity from an ExpandableListActivity instead of just a ListActivity, I created a static helper class for producing a SimpleExpandableListAdapter given a set of items:

public class ExpandableEntryListAdapterHelper {
 
        // identifiers we'll use to map content in the groupData maps to resource identifiers
	private static final String GROUP_RESOURCE_CONTENTS_1 = "GROUP_RESOURCE_CONTENTS_1";
	private static final String GROUP_RESOURCE_CONTENTS_2 = "GROUP_RESOURCE_CONTENTS_2";
 
        // the ordered array of identifiers that line up with the groupTo array
	private static final String[] groupFrom = { GROUP_RESOURCE_CONTENTS_1, GROUP_RESOURCE_CONTENTS_2 };
        // the ordered array of resource IDs that will be populated in the group list items
	private static final int[] groupTo = { R.id.group_resource_one, R.id.group_resource_two };
 
        // identifiers we'll use to map content in the childData maps to resource identifiers
	private static final String ENTRY_RESOURCE_CONTENTS_1 = "ENTRY_RESOURCE_CONTENTS_1";
	private static final String ENTRY_RESOURCE_CONTENTS_2 = "ENTRY_RESOURCE_CONTENTS_2";
 
        // the ordered array of identifiers that line up with the childTo array.
	private static final String[] childFrom = { ENTRY_RESOURCE_CONTENTS_1, ENTRY_RESOURCE_CONTENTS_2 };
        // list of resource IDs that will be populated in the child list items
	private static final int[] childTo = { R.id.entry_resource_one, R.id.entry_resource_two };
 
	private static final SimpleDateFormat dateFormat = new SimpleDateFormat(
			"MM/dd/yyyy hh:mm a");
 
	public static ExpandableListAdapter getInstance(Context context,
			List entries) {
 
		TreeMap<String, Object> groupMap = new TreeMap<String, Object>();
 
		for (Entry e : entries) {
			Date entryDate = e.getStop();
			Date day = new Date(entryDate.getYear(), entryDate.getMonth(),
					entryDate.getDate());
			if (!groupMap.containsKey(day)) {
				groupMap.put(day, new ArrayList());
			}
 
			groupMap.get(day).add(e);
		}
 
		List<Map> groupData = new ArrayList<Map>();
		List<List<Map>>; childData = new ArrayList<List<Map>>();
 
		for (Date groupDate : groupMap.keySet()) {
			ArrayList groupEntries = groupMap.get(groupDate);
 
			MeasurementType setting = SettingsActivity.getMeasurementType(context);
 
			Map groupValues = new HashMap();
			groupValues.put(GROUP_DATE, shortDateFormat.format(groupDate));
			groupValues.put(GROUP_MEASUREMENT_TYPE, setting.getAbbr());
 
			ArrayList&lt;Map&gt; groupEntryDataMap = new ArrayList&lt;Map&gt;();
 
			Double sumOfEntries = 0.0;
			for(Entry entry : groupEntries){
				Double entryMeasurement = entry.getTotalMeasurement(setting).get();
 
				Map entryValues = new HashMap();
				entryValues.put(ENTRY_MEASUREMENT, measFormat.format(entry.getTotalMeasurement(setting).get()));
				entryValues.put(ENTRY_MEASUREMENT_TYPE, setting.getAbbr());
				entryValues.put(ENTRY_TIME_SPAN, df.format(entry.getDurationMinutes()) + " minutes");
				entryValues.put(ENTRY_DATE_TIME, dateFormat.format(entry.getStop()));
				entryValues.put(ENTRY, entry);
 
				groupEntryDataMap.add(entryValues);
 
				sumOfEntries += entryMeasurement;
			}
			groupValues.put(GROUP_MEASUREMENT, measFormat.format(sumOfEntries));
 
			childData.add(groupEntryDataMap);
			groupData.add(groupValues);
		}
 
		return new SimpleExpandableListAdapter(context, groupData,
				R.layout.entry_list_group, groupFrom, groupTo, childData,
				R.layout.entry_list_item, childFrom, childTo);
	}
}