The solution ended up being a custom ArrayAdapter
subclass which prepends a filter before the ArrayFilter
even sees it.
The change to the main application is minimal, it just needs to instantiate the newly-christened WtfArrayAdapter
and pass its constructor an extra argument: an object reference to the object containing the normalisation method (in the current äpp’s design, that’s the MainActivity
class, a future refactor will do better):
- ArrayAdapter acronymKeys = new ArrayAdapter(this,
- android.R.layout.simple_list_item_1, sorted);
+ ArrayAdapter acronymKeys = new WtfArrayAdapter(this,
+ android.R.layout.simple_list_item_1, sorted, this);
The custom WtfArrayAdapter
must be able to call methods from ArrayFilter
(which is ArrayAdapter
’s internal private class), so it needs to belong to package android.widget;
. I’ll spare you the full imports, comments, etc. and will reproduce the important parts below:
public class WtfArrayAdapter<T> extends ArrayAdapter<T> {
New members for:
- the pre-filter normalisation method’s object
- our internal private class’ object
- the parent’s internal private class’ object (ArrayAdapter.mFilter
is private
, unfortunately)
private MainActivity sParent;
private WtfArrayFilter sFilter;
private Filter pFilter;
The extended constructor (we need to implement only the one we’re actually calling):
- call the inherited constructor
- store away the parent’s mFilter
value
- instantiate our own WtfArrayFilter
- store away the pre-filter normalisation method’s object, as WtfArrayFilter
will need it later
public WtfArrayAdapter(Context context, @LayoutRes int resource,
@NonNull T[] objects, MainActivity parent) {
super(context, resource, 0, Arrays.asList(objects));
sParent = parent;
sFilter = new WtfArrayFilter();
pFilter = super.getFilter();
}
Override ArrayAdapter
’s getFilter()
method to always return our new WtfArrayFilter
:
public Filter getFilter() {
return sFilter;
}
Implementation of WtfArrayFilter
as Filter
subclass just like ArrayFilter
does, and forwarding all boring (i.e. unchanged) calls to the inherited ArrayFilter
:
private class WtfArrayFilter extends Filter {
protected void publishResults(CharSequence constraint,
FilterResults results) {
pFilter.publishResults(constraint, results);
}
We only need to change one method to do our own filtering before calling the inherited ArrayFilter
’s filtering method:
protected FilterResults performFiltering(CharSequence prefix) {
return pFilter.performFiltering(prefix == null ? null :
sParent.normaliseAcronym(prefix.toString()));
}
}
}
Improvements welcome, I’m still a Java™ beginner.