Vista de Autocompletar texto con adaptador personalizado y filtro

Estoy intentando establecer un ArrayAdapter personalizado para mi AutoCompleteTextView como este

 public class AutoCompleteContactArrayAdapter extends ArrayAdapter<Map> implements Filterable { private Context mContext; private List<Map> mContactList; public AutoCompleteContactArrayAdapter(Context context, List<Map> objects) { super(context, R.layout.auto_contact_list, objects); mContext = context; mContactList = objects; // TODO Auto-generated constructor stub } @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 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) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } @Override protected FilterResults performFiltering(CharSequence constraint) { ArrayList result = new ArrayList(); result.add("test"); result.add("another"); result.add("last"); FilterResults r = new FilterResults(); r.values = result; r.count = result.size(); return r; } }; } } 

En la depuración, la aplicación está ingresando los métodos de filter tanto publishResults() como performFiltering() pero el conjunto de resultados que se muestra no es mi array prueba [test, another, last] sino que muestra todos los resultados ignorando mi filtro.

Aquí está la implementación actual de mi código:

El xml

  

El adaptador:

 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 implements Filterable { private ArrayList fullList; private ArrayList mOriginalValues; private ArrayFilter mFilter; public AutoCompleteAdapter(Context context, int resource, int textViewResourceId, List objects) { super(context, resource, textViewResourceId, objects); fullList = (ArrayList) objects; mOriginalValues = new ArrayList(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(fullList); } } if (prefix == null || prefix.length() == 0) { synchronized (lock) { ArrayList list = new ArrayList(mOriginalValues); results.values = list; results.count = list.size(); } } else { final String prefixString = prefix.toString().toLowerCase(); ArrayList values = mOriginalValues; int count = values.size(); ArrayList newValues = new ArrayList(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) results.values; }else{ fullList = new ArrayList(); } if (results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } } } 

Y finalmente en el código inicializar así …

  ArrayList searchArrayList= new ArrayList(); //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); 

Hecho 🙂

Está bien, creo que entiendo lo que Luksprog estaba diciendo que este código funciona ahora que la clave es esta

 mContactList = (ArrayList>) results.values; 

en

 @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 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>) results.values; notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } @Override protected FilterResults performFiltering(CharSequence constraint) { ArrayList> result = new ArrayList>(); HashMap myMap = new HashMap(); myMap.put("name", "key"); result.add(myMap); HashMap myMap2 = new HashMap(); myMap2.put("name", "is"); result.add(myMap2); HashMap myMap3 = new HashMap(); myMap3.put("name", "another"); result.add(myMap3); FilterResults r = new FilterResults(); r.values = result; r.count = result.size(); return r; } }; } 

Autocompletetextview usa Adapter para mostrar el menú desplegable de sugerencias automáticas completas.

Adapater debe ser filtrable y debe dar vista poblando datos para cada elemento de la lista de datos. Autocompletetextview utiliza un filtro definido en el adaptador para obtener resultados y mostrarlos.

Por lo tanto, si necesita crear un adaptador personalizado, debe proporcionar implementación para getView y proporcionar una clase de filtro.

Ejemplo de trabajo completo de diseño personalizado autocompletetextview y adaptador personalizado

http://www.zoftino.com/android-autocompletetextview-custom-layout-and-adapter