expandable list view filters

ExpandableListViews are tricky. They make sense when you’re done implementing one, but extending BaseExpandableListAdapter and then having your IDE fill in all the methods you need to override can be pretty overwhelming. A question I had when working on mine was whether it was possible to implement a Filter for one. It is, but oddly the answer to that question was not available anywhere on the internet.

There are a few additions you need to make in order to turn a regular ListView into a filtered ExpandableListView:

  1. Instead of being backed by an array-like collection, your Adapter must be backed by a collection of collections. The top-level collection corresponds to the items you can click on to expand; the internal collections correspond to the items that show when you expand their parent.
  2. Your adapter should contain two such backing collections: one which contains the full dataset, and one into which we place the filtered dataset.
  3. There are various getters for which implementation is required (for example: getChild, getGroupCount, etc;) their purposes are for the most part obvious if you’ve ever implemented a standard ListView. The getGroupView and getChildView methods are very similar to getView, with just a few distinctions in this case:

    In order to implement the view-holder pattern, it’s necessary to create two holder classes – one for group views, and one for child views. Also, note that the data you will populate these views with should come from the filtered dataset.
  4. Finally, implement a class that extends Filter:

    As implemented above, any groups that contain children which match the constraint (in this case, a CharSequence) will be shown, along with those children. If the constraint is invalid (for example, the user left the EditText you got the constraint from empty) the filter returns the entire original dataset.

Add in a few layout XMLs and some way of calling filter(String) on your Filter (perhaps an EditText and a TextWatcher), and you’ve got yourself a filtered ExpandableListView.