5

Fuera de la caja, el widget AutoCompleteTextView no parece ser capaz de coincidir con la cadena de entrada en el medio de un valor de lista; las coincidencias siempre se hacen al principio; por ejemplo, ingresar "ar" coincide con "argentina", pero no "hungary".Comportamiento AutoCompleteTextView personalizado

¿Cómo puedo buscar el texto en el medio de la palabra? ¿Alguien puede darme una idea?

¡Gracias de antemano!

+0

estoy haciendo algo similar aquí !!! http://stackoverflow.com/questions/12854336/autocompletetextview-backed-by-cursorloader – toobsco42

Respuesta

5

Debería escribir una clase personalizada Filter e implementar el método performFiltering usted mismo. Este método toma un argumento CharSequence, que puede usar para realizar cualquier operación de cadena que necesite para generar una lista de coincidencias de su conjunto de datos (en su caso, podría usar String.contains en lugar de String.startsWith). La función performFiltering no se ejecuta en el subproceso de la interfaz de usuario.

A continuación, regrese a su lista de coincidencias como un objeto FilterResults, que contiene un Objectvalores (su lista de coincidencias, probablemente un ArrayList) y un recuento int que es el tamaño de su lista de coincidencias.

Finalmente, implemente el método de devolución de llamada publishResults, que regresa una vez que el hilo de trabajo ha generado la lista de coincidencias, lo que le permite llamar al notifyDataSetChanged en su adaptador AutoCompleteTextView para que pueda mostrar los resultados.

+0

¿me puede dar un ejemplo? – Chrishan

+0

Sé que ha pasado mucho tiempo desde esta respuesta, pero es uno de los más precisos que encontré con respecto a este tema (y uno de los más difíciles de encontrar, por cierto). ¡Gracias! – nKn

+1

Victor tiene razón, aquí está la manera fácil: simplemente copie y pegue todo el contenido de android.widget.ArrayAdapter en una nueva clase llamada CustomArrayAdapter y cambie las 2 instancias "startsWith" ubicadas en performFiltering y publishResults por "contains". Sencillo. –

0

Mi consejo sería analizar la cadena en una matriz de caracteres. Luego itere cada carácter hasta que encuentre la cadena.

Por ejemplo digamos su búsqueda quería volver con todas las palabras "comió" en ellos y la lista de palabras era ...

estado rasgo berate finales

Su algoritmo debe ser algo como este

Tome la cuerda y analizarlo en un array de caracteres recorrer la matriz y encontrar el primer "carácter correcto" (en nuestro ejemplo la 'a') una vez que se encontró que el carácter de comprobación de n Carácter ext., sigue comprobando cada carácter de una coincidencia hasta que se complete el valor que se busca. Si el personaje no es una coincidencia, salga de la iteración de la matriz y vaya a la siguiente palabra.

3

Pregunta anterior, pero sigue siendo relevante. Siguiendo la guía de algunas otras preguntas, implementó un adaptador personalizado con filtro. Hice un adaptador genérico simple que busca con contains. Notas rápidas sobre él:

Estoy usando butterknife, pero es fácil de hacer el viewHolder con findviewbyid.

El diseño R.layout.list_item_simple es un diseño simple con la vista de texto R.id.text_view_simple.

El objeto necesita un toString que se comparará.

public class SimpleContainsAutocompleteAdapter <T> extends ArrayAdapter<T> implements Filterable { 
    private List <T> listObjects; 
    List<T> suggestions = new ArrayList<>(); 
    private int resource; 

    private Filter mFilter = new Filter(){ 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      FilterResults filterResults = new FilterResults(); 

      if(constraint != null) { 
       suggestions.clear(); 
       for(T object : listObjects){ 
        if(object.toString().toLowerCase().contains(constraint.toString().toLowerCase())){ 
         suggestions.add(object); 
        } 
       } 

       filterResults.values = suggestions; 
       filterResults.count = suggestions.size(); 
      } 

      return filterResults; 
     } 

     @Override 
     protected void publishResults(CharSequence contraint, FilterResults results) { 
      if(results == null){ 
       return; 
      } 

      List<T> filteredList = (List<T>) results.values; 
      if(results.count > 0) { 
       clear(); 
       for (T filteredObject : filteredList) { 
        add(filteredObject); 
       } 
       notifyDataSetChanged(); 
      } 
     } 
    }; 

    public SimpleContainsAutocompleteAdapter(Context context, List<T> listObjects) { 
     super(context, R.layout.list_item_simple, listObjects); 
     this.listObjects = new ArrayList<>(listObjects); 
     this.resource = R.layout.list_item_simple; 
    } 

    @Override 
    public Filter getFilter() { 
     return mFilter; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     Object listObject = getItem(position); 
     viewHolder holder; 
     if(convertView != null) { 
      holder = (viewHolder) convertView.getTag(); 
     }else{ 
      convertView = LayoutInflater.from(getContext()).inflate(resource, parent, false); 
      holder = new viewHolder(convertView); 
      convertView.setTag(holder); 
     } 

     holder.name.setText(listObject.toString()); 

     return convertView; 
    } 


    static class viewHolder { 
     @InjectView(R.id.text_view_simple) TextView name; 

     public viewHolder(View view) { 
      ButterKnife.inject(this, view); 
     } 
    } 
} 
+0

Esta es la respuesta, tuve que cambiar algunas cosas, pero funciona perfecto. – sdelvalle57

1
public class AutoCompleteAdapter <T> extends ArrayAdapter<T> implements Filterable { 
    private List <T> listObjects; 
    List<T> suggestions = new ArrayList<>(); 
    private Context context; 
    public AutoCompleteAdapter(Context context, List<T> listObjects) { 
     super(context, R.layout.list_item_simple, listObjects); 
     this.listObjects = new ArrayList<>(listObjects); 
     this.context = context; 
    } 
    private Filter mFilter = new Filter(){ 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      FilterResults filterResults = new FilterResults(); 
      if(constraint != null) { 
      suggestions.clear(); 
       for(T object : listObjects){ 
        if(object.toString().toLowerCase().contains(constraint.toString().toLowerCase())){      suggestions.add(object); 
       } 
      } 

      filterResults.values = suggestions; 
      filterResults.count = suggestions.size(); 
     } 
     return filterResults; 
    } 

    @Override 
    protected void publishResults(CharSequence constraint, FilterResults results) { 
     if(results == null){ 
      return; 
     } 
     List<T> filteredList = (List<T>) results.values; 
     if(results.count > 0) { 
      clear(); 
      for (T filteredObject : filteredList) { 
       add(filteredObject); 
      } 
      notifyDataSetChanged(); 
     } 
    } 
}; 
@Override 
public Filter getFilter() { 
    return mFilter; 
} 
private static class ViewHolder { 
    TextView title; 
} 
@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    Object listObject = getItem(position); 
    final ViewHolder viewHolder; // view lookup cache stored in tag 
    if (convertView == null) { 
     viewHolder = new ViewHolder(); 
     LayoutInflater inflater = LayoutInflater.from(getContext()); 
     convertView = inflater.inflate(R.layout.list_item_simple, parent, false); 
     viewHolder.title = (TextView) convertView.findViewById(R.id.title); 
     convertView.setTag(viewHolder); 
    } else { 
     viewHolder = (ViewHolder) convertView.getTag(); 
    } 
    viewHolder.title.setText(listObject.toString()); 
    return convertView; 
} 

}

Cuestiones relacionadas