Auto-complete
From Google Material Design documentation.
Use auto-complete text fields to present real-time suggestions or completions in dropdowns, so users can enter information more accurately and efficiently.
How to add?¶
I. Declare your AutoCompleteTextView
inside any layout.xml
.
<AutoCompleteTextView
android:id="@+id/autocompleteView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Search dogs..."/>
II. Define a string-array
that contains all text suggestions in a file inside res/values
directory.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="dogs_list">
<item>Bichon Frise</item>
<item>Border Collie</item>
<item>Border Terrier</item>
<item>Boxer</item>
<item>Chihuahua</item>
<item>German Shepherd</item>
<item>Golden Retriever</item>
<item>Greyhound</item>
</string-array>
</resources>
III. Define a filterable list adapter
to manage the auto completion data list.
int layoutItemId = android.R.layout.simple_dropdown_item_1line;
String[] dogArr = getResources().getStringArray(R.array.dogs_list);
List<String> dogList = Arrays.asList(dogsArr);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, layoutItemId, dogList);
AutoCompleteTextView autocompleteView =
(AutoCompleteTextView) findViewById(R.id.autocompleteView);
autocompleteView.setAdapter(adapter);
How to style?¶
I. Declare custom styles in your styles.xml
file.
<style name="Autocomplete" parent="Widget.AppCompat.Light.AutoCompleteTextView">
<item name="android:background">@color/green500</item>
<item name="colorControlNormal">@color/amber500</item>
<item name="colorControlActivated">@color/cyan500</item>
</style>
II. Apply this style to the AutoCompleteTextView
via android:theme
attribute.
<AutoCompleteTextView
android:id="@+id/autocomplete_dogs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Autocomplete"
android:hint="Search dogs..." />
Drop down anchor¶
By default, the dropdown list with your filtered data appear just below the AutoCompleteTextView
.
To change this position use dropDownAnchor
attribute and reference another view id.
<AutoCompleteTextView
android:id="@+id/autocomplete_dogs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Autocomplete"
android:hint="Search dogs..."
android:dropDownAnchor="@+id/header"
android:dropDownWidth="match_parent"
/>
Custom Adapter¶
To fully customize the dropdown list you need to provide your own Adapter
. It needs to implement Filterable
and ListAdapter
interfaces.
The easiest way to achieve this is by extending ArrayAdapter
which already implements both interfaces.
I. Create a custom adapter extending ArrayAdapter
class.
II. Create a custom filter extending Filter
class and provide your own filtering logic overriding performFiltering
method.
class DogsFilter extends Filter {
AutoCompleteDogsAdapter adapter;
List<Dog> originalList;
List<Dog> filteredList;
public DogsFilter(AutoCompleteDogsAdapter adapter, List<Dog> originalList) {
super();
this.adapter = adapter;
this.originalList = originalList;
this.filteredList = new ArrayList<>();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
filteredList.clear();
final FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(originalList);
} else {
final String filterPattern = constraint.toString().toLowerCase().trim();
// Your filtering logic goes in here
for (final Dog dog : originalList) {
if (dog.breed.toLowerCase().contains(filterPattern)) {
filteredList.add(dog);
}
}
}
results.values = filteredList;
results.count = filteredList.size();
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.filteredDogs.clear();
adapter.filteredDogs.addAll((List) results.values);
adapter.notifyDataSetChanged();
}
}
III. Provide your custom filter from your adapter class by overriding getFilter()
method.
class AutoCompleteDogsAdapter extends ArrayAdapter<Dog> {
private final List<Dog> dogs;
private List<Dog> filteredDogs = new ArrayList<>();
public AutoCompleteDogsAdapter(Context context, List<Dog> dogs) {
super(context, 0, dogs);
this.dogs = dogs;
}
@Override
public int getCount() {
return filteredDogs.size();
}
@Override
public Filter getFilter() {
return new DogsFilter(this, dogs);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item from filtered list.
Dog dog = filteredDogs.get(position);
// Inflate your custom row layout as usual.
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.row_dog, parent, false);
TextView tvName = (TextView) convertView.findViewById(R.id.row_breed);
ImageView ivIcon = (ImageView) convertView.findViewById(R.id.row_icon);
tvName.setText(dog.breed);
ivIcon.setImageResource(dog.drawable);
return convertView;
}