Reputation: 13761
In many places I've seen different ways of autocompletion, ones I considered very basic, others very well implemented.
My idea is having an AutoCompleteTextView
but customizing its way of autocompletion. For example, all my autocompletion suggestions will be one-worded strings, where spaces are replaced by dashs (-). If I have a suggestion like last-night-I-was-bad
, my goal would be that if the user enters one of the first letters of any word (I mean: l
, n
, I
, w
or b
) the suggestion would be shown. Summarizing: treat dashes as spaces and showing the suggestions that match any substring of any 'word'. This kind of autocompletions I consider really useful!
I'd also be interested in discarding some of the characters from the suggestions. For example, suppose all my autosuggestions start with @
, and the user enters the a
letter, then all suggestions starting with @a
would be shown.
Is there something like this, or at least is it possible to customize the way AutoCompleteTextView
handles the suggestions? I had a look at the documentation but didn't see something like that (or at least, not as direct).
Any help appreciated!
Upvotes: 0
Views: 597
Reputation: 13761
Finally I got it. I made an ArrayAdapter
extension, which has an internal Filter
extension, and overriding performFiltering(CharSequence)
and publishResults(CharSequence, FilterResults)
I was able to implement the behavior I needed (basically compare two String
s using contains()
instead of default startsWith()
).
The code would be something like this, hope it may help someone.
public class SubstringFilterArrayAdapter<T> extends ArrayAdapter<T> implements Filterable {
// Needed data structures
...
final List<T> objects;
final CustomFilter myfilter = new CustomFilter();
...
public SubstringFilterArrayAdapter(final Context context_, final int tvResId_, final List<T> objects_) {
objects = objects_;
...
}
@Override
public Filter getFilter() {
...
}
private class CustomFilter extends Filter {
@Override
protected FilterResults performFiltering(final CharSequence prefix) {
final FilterResults results = new FilterResults();
final ArrayList<T> matched = new ArrayList<T>();
// Put in matched the results that match the prefix using your own implementation
...
results.values = matched;
results.count = matched.size();
return results;
}
@Override
protected void publishResults(final CharSequence constraint, final FilterResults results) {
objects = (List<T>) results.values;
if (results.count > 0)
notifyDataSetChanged();
else
notifyDataSetInvalidated();
}
}
@Override
public int getCount() {
return objects.size();
}
@Override
public T getItem(int position) {
return objects.get(position);
}
}
Upvotes: 1