Autocompletetextview with custom adapter and filter
Solution 1:
Here is the current implementation of my code:
The xml
<AutoCompleteTextView
android:id="@+id/searchAutoComplete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:layout_toRightOf="@+id/linearLayout1"
android:background="@drawable/abs__textfield_search_default_holo_light"
android:drawableLeft="@drawable/abs__ic_search_api_holo_light"
android:drawableRight="@drawable/abs__ic_clear_holo_light"
android:hint="@string/search"
android:imeOptions="actionSearch"
android:inputType="textAutoComplete|textAutoCorrect" >
The adapter:
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
public class AutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {
private ArrayList<String> fullList;
private ArrayList<String> mOriginalValues;
private ArrayFilter mFilter;
public AutoCompleteAdapter(Context context, int resource, int textViewResourceId, List<String> objects) {
super(context, resource, textViewResourceId, objects);
fullList = (ArrayList<String>) objects;
mOriginalValues = new ArrayList<String>(fullList);
}
@Override
public int getCount() {
return fullList.size();
}
@Override
public String getItem(int position) {
return fullList.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return super.getView(position, convertView, parent);
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ArrayFilter();
}
return mFilter;
}
private class ArrayFilter extends Filter {
private Object lock;
@Override
protected FilterResults performFiltering(CharSequence prefix) {
FilterResults results = new FilterResults();
if (mOriginalValues == null) {
synchronized (lock) {
mOriginalValues = new ArrayList<String>(fullList);
}
}
if (prefix == null || prefix.length() == 0) {
synchronized (lock) {
ArrayList<String> list = new ArrayList<String>(mOriginalValues);
results.values = list;
results.count = list.size();
}
} else {
final String prefixString = prefix.toString().toLowerCase();
ArrayList<String> values = mOriginalValues;
int count = values.size();
ArrayList<String> newValues = new ArrayList<String>(count);
for (int i = 0; i < count; i++) {
String item = values.get(i);
if (item.toLowerCase().contains(prefixString)) {
newValues.add(item);
}
}
results.values = newValues;
results.count = newValues.size();
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results.values!=null){
fullList = (ArrayList<String>) results.values;
}else{
fullList = new ArrayList<String>();
}
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}
And finally in code initialize like this...
ArrayList<String> searchArrayList= new ArrayList<String>();
//initilaze this array with your data
AutoCompleteAdapter adapter = new AutoCompleteAdapter(this, android.R.layout.simple_dropdown_item_1line, android.R.id.text1, searchArrayList);
autoCompleteTextView = (AutoCompleteTextView) customNav.findViewById(R.id.searchAutoComplete);
autoCompleteTextView.setAdapter(adapter);
Done :)
Solution 2:
Okay i think i figure out what Luksprog was saying this code works now they key is this
mContactList = (ArrayList<Map<String, String>>) results.values;
in
@Override
public int getCount(){
return mContactList.size();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.auto_contact_list, parent,
false);
TextView nameView = (TextView) rowView.findViewById(R.id.ccontName);
TextView phoneView = (TextView) rowView.findViewById(R.id.ccontNo);
TextView typeView = (TextView) rowView.findViewById(R.id.ccontType);
Map<String, String> contactMap = mContactList.get(position);
nameView.setText(contactMap.get("name"));
phoneView.setText(contactMap.get("phone"));
typeView.setText(contactMap.get("type"));
return rowView;
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
if (results.count > 0) {
mContactList = (ArrayList<Map<String, String>>) results.values;
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<Map<String, String>> result = new ArrayList<Map<String, String>>();
HashMap<String,String> myMap = new HashMap<String,String>();
myMap.put("name", "key");
result.add(myMap);
HashMap<String,String> myMap2 = new HashMap<String,String>();
myMap2.put("name", "is");
result.add(myMap2);
HashMap<String,String> myMap3 = new HashMap<String,String>();
myMap3.put("name", "another");
result.add(myMap3);
FilterResults r = new FilterResults();
r.values = result;
r.count = result.size();
return r;
}
};
}
Solution 3:
Autocompletetextview uses Adapter to show auto complete suggestion drop down.
Adapater should be filterable and should give view populating data for each item from data list. Autocompletetextview uses filter defined in the adapter to get results and show them.
So, if you need to create custom adapter, you need to provide implementation for getView and provide a filter class.
Complete working example of autocompletetextview custom layout and custom adapter
http://www.zoftino.com/android-autocompletetextview-custom-layout-and-adapter