In my app I have an AutoCompleteTextView which allowed users to select suburbs by typing a few characters and then selecting from a pre-defined list.
The issue was I wanted the option to also filter by postcode, but this required the postcode to be part of the Suburb.toString() function, making it rather ugly upon display.
There are two obvious ways to skin this cat; customise the filtering in Adapter.getFilter() or override the text shown in Adapter.getView().
Just for reference, my Suburb.toString() returns "Name of Suburb : #" where # is the postcode.
Option A - Subclass the adapter
The former is relatively easy, just subclass an ArrayAdapter (or whatever adapter you're using), copy the code from ArrayAdapter.ArrayFilter and change the text source "valueText = value.toString().toLowerCase()" to suburb/postcode.
Change Suburb.toString() to only display the suburb name.
Sadly, I didn't choose this option first.
Option B - Override the view text
The latter is to keep Suburb.toString() but replace the item TextView text after it's been rendered. I chose this solution, thinking it'd be easier. It wasn't.
final AutoCompleteTextView tvSuburbs;
ArrayAdapter<Suburb> adapterSuburbs;
adapterSuburbs = new ArrayAdapter<Suburb>(this.getSupportActionBar().getThemedContext(), android.R.layout.select_dialog_item, suburbs) {
// Hide the postcode from the display
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = (TextView) super.getView(position, convertView, parent);
Suburb s = getItem(position);
tv.setText(s.name);
return tv;
}
};
tvSuburbs = (AutoCompleteTextView) layout.findViewById(R.id.actvSuburb);
tvSuburbs.setAdapter(adapterSuburbs);
Now that's all fine and dandy. Simply override the getView() of the adapter and change the text after it's been returned. The filtering still works as the value string is still the same.
There's only one problem left. Now that your autocompletion works, selecting an item from the dropdown will set the text to "Name of Suburb : #".
That's simple enough right? Override AutoCompleteTextView.setOnItemSelectedListener() and call setText(), can't be that hard.
Yes. Yes it is. Starting from ICS, that function only sets the listener. Whether or not it actually does anything is another story!
Taking a look at the AutoCompleteTextView source code, I realised it actually did not do anything! You can set/get the listener but it's never used in the code!
Instead, use setOnItemClickListener() and call setText() from there.
Now it's working.
- User types in a few search characters
- Allows user to filter by suburb name AND/OR postcode
- Dropdown showing only suburb name
- User clicks on the item
- Auto-completes the text using only the suburb name
Sweet, it works! So... what's our problem now? I'm sure you'll notice once you run the app once.
The behaviour of the dropdown is to show the dropdown whenever you call setText(). That means it'll display the dropdown after you click an item in the autocomplete.
That behaviour is pretty stupid in my opinion, but there's a workaround!