Vista de lista Filtro Android

He creado una vista de lista en Android y quiero agregar texto de edición sobre la lista y cuando el usuario ingresa texto, la lista se filtrará de acuerdo con la entrada del usuario.

¿Puede alguien decirme por favor si hay una manera de filtrar el adaptador de lista en Android?

Sí. Agregue un EditText en la parte superior de la vista de lista en su archivo de diseño aml. Y en tu actividad / fragmento …

lv = (ListView) findViewById(R.id.list_view); inputSearch = (EditText) findViewById(R.id.inputSearch); // Adding items to listview adapter = new ArrayAdapter(this, R.layout.list_item, R.id.product_name, products); lv.setAdapter(adapter); inputSearch.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { // When user changed the Text MainActivity.this.adapter.getFilter().filter(cs); } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { } @Override public void afterTextChanged(Editable arg0) {} }); 

Lo básico aquí es agregar un OnTextChangeListener a su texto de edición y dentro de su método de callback aplicar filtro al adaptador de su lista de visualización.

EDITAR

Para obtener el filtro de su BaseAdapter personalizado, deberá implementar la interfaz Filterable .

 class CustomAdapter extends BaseAdapter implements Filterable { public View getView(){ ... } public Integer getCount() { ... } @Override public Filter getFilter() { Filter filter = new Filter() { @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { arrayListNames = (List) results.values; notifyDataSetChanged(); } @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); ArrayList FilteredArrayNames = new ArrayList(); // perform your search here using the searchConstraint String. constraint = constraint.toString().toLowerCase(); for (int i = 0; i < mDatabaseOfNames.size(); i++) { String dataNames = mDatabaseOfNames.get(i); if (dataNames.toLowerCase().startsWith(constraint.toString())) { FilteredArrayNames.add(dataNames); } } results.count = FilteredArrayNames.size(); results.values = FilteredArrayNames; Log.e("VALUES", results.values.toString()); return results; } }; return filter; } } 

Dentro de perfromFiltering () necesita hacer una comparación real de la consulta de búsqueda con los valores de su base de datos. Pasará su resultado al método publishResults () .

Implemente su adaptador Filtrable:

 public class vJournalAdapter extends ArrayAdapter implements Filterable{ private ArrayList items; private Context mContext; .... 

luego crea tu clase de filtro:

 private class JournalFilter extends Filter{ @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults result = new FilterResults(); List allJournals = getAllJournals(); if(constraint == null || constraint.length() == 0){ result.values = allJournals; result.count = allJournals.size(); }else{ ArrayList filteredList = new ArrayList(); for(JournalModel j: allJournals){ if(j.source.title.contains(constraint)) filteredList.add(j); } result.values = filteredList; result.count = filteredList.size(); } return result; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { if (results.count == 0) { notifyDataSetInvalidated(); } else { items = (ArrayList) results.values; notifyDataSetChanged(); } } } 

De esta forma, su adaptador es Filtrable, puede pasar el elemento del filtro al filtro del adaptador y hacer el trabajo. Espero que esto sea útil.

En caso de que alguien todavía esté interesado en este tema, creo que el mejor enfoque para filtrar listas es crear una clase de filtro genérica y usarla con algunas técnicas de reflexión básica / generics contenidas en el paquete SDK de la vieja escuela de Java. Esto es lo que hice:

 public class GenericListFilter extends Filter { /** * Copycat constructor * @param list the original list to be used */ public GenericListFilter (List list, String reflectMethodName, ArrayAdapter adapter) { super (); mInternalList = new ArrayList<>(list); mAdapterUsed = adapter; try { ParameterizedType stringListType = (ParameterizedType) getClass().getField("mInternalList").getGenericType(); mCompairMethod = stringListType.getActualTypeArguments()[0].getClass().getMethod(reflectMethodName); } catch (Exception ex) { Log.w("GenericListFilter", ex.getMessage(), ex); try { if (mInternalList.size() > 0) { T type = mInternalList.get(0); mCompairMethod = type.getClass().getMethod(reflectMethodName); } } catch (Exception e) { Log.e("GenericListFilter", e.getMessage(), e); } } } /** * Let's filter the data with the given constraint * @param constraint * @return */ @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); List filteredContents = new ArrayList<>(); if ( constraint.length() > 0 ) { try { for (T obj : mInternalList) { String result = (String) mCompairMethod.invoke(obj); if (result.toLowerCase().startsWith(constraint.toString().toLowerCase())) { filteredContents.add(obj); } } } catch (Exception ex) { Log.e("GenericListFilter", ex.getMessage(), ex); } } else { filteredContents.addAll(mInternalList); } results.values = filteredContents; results.count = filteredContents.size(); return results; } /** * Publish the filtering adapter list * @param constraint * @param results */ @Override protected void publishResults(CharSequence constraint, FilterResults results) { mAdapterUsed.clear(); mAdapterUsed.addAll((List) results.values); if ( results.count == 0 ) { mAdapterUsed.notifyDataSetInvalidated(); } else { mAdapterUsed.notifyDataSetChanged(); } } // class properties private ArrayAdapter mAdapterUsed; private List mInternalList; private Method mCompairMethod; } 

Y luego, lo único que debe hacer es crear el filtro como clase de miembro (posiblemente dentro de “onCreate” de la vista) pasando su referencia de adaptador, su lista y el método que se solicitará para el filtrado:

 this.mFilter = new GenericFilter (list, "getName", adapter); 

Lo único que falta ahora es anular el método “getFilter” en la clase de adaptador:

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

¡Todo listo! Debe filtrar su lista con éxito. Por supuesto, también debe implementar su algoritmo de filtro de la mejor manera que describa su necesidad, el siguiente código es solo un ejemplo. . Espero que haya sido de ayuda, cuídate.