Buscar a través de RecyclerView usando Searchview
Quiero buscar a través de RecyclerView
, Tengo List<BaseOfCards>
(BaseOfCards es mi getter & setter class) Mi RecyclerViewAdapter :
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> { private LayoutInflater inflater; private List<BaseOfCards> items; //private int itemLayout; //String cardvalue; private Activity mActivity; public RecyclerViewAdapter(Activity mActivity, Context context, List<BaseOfCards> items) { this.mActivity = mActivity; inflater = LayoutInflater.from(context); this.items = items; //this.itemLayout = itemLayout; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.custom_row, parent, false); MyViewHolder holder = new MyViewHolder(view, mActivity); return holder; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { BaseOfCards item = items.get(position); holder.title.setTag(item); holder.title.setText(item.getCardName()); } @Override public int getItemCount() { return items.size(); } public static class MyViewHolder extends RecyclerView.ViewHolder { private Activity mActivity; TextView title; ImageView titileImageView; public MyViewHolder(View itemView, Activity mActivity) { super(itemView); titileImageView = (ImageView) itemView.findViewById(R.id.image_country); title = (TextView) itemView.findViewById(R.id.listText); this.mActivity = mActivity; } } }
Añado SearchView a mi menú y lo inicializo en MainActivity :
- Implementación de SearchView en la barra de acción
- Centre SearchView en la barra de acciones
- Icono de Android SearchView
- SearchView no filtrar en cada niño Tab de TabLayout
- Adición de SearchView en el fragmento
MenuItem menuItem = menu.findItem(R.id.action_search1); searchView = (SearchView) MenuItemCompat.getActionView(menuItem); SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); searchView.setIconifiedByDefault(true);
¿Qué necesito hacer a continuación? Hacer que mi RecyclerViewAdapter implement Filterable
o qué? O simplemente hacer filter
clase en * RecyclerViewAdapter ** y simplemente llamar desde mi MainActivity ?
- Cambiar el texto de SearchView y el color de la sugerencia de appcompat
- Botón del micrófono ActionBar (búsqueda por voz) en SearchView
- Restaurar el estado del widget de vista de búsqueda de android
- Android - vista de búsqueda con función completa automática dentro de la barra de acción
- No se puede mostrar el teclado automáticamente en el SearchView
- ¿Cómo implementar WhatsApp como el diseño de materiales SearchView?
- Android ActionBar Personalizar Buscar Ver
- Filtro de búsquedaVer ListView
He resuelto mi problema
-
Hacer mi clase RecyclerViewAdapter
implements Filterable
-
Agregar línea
private List<BaseOfCards> orig;
-
Agregue el método
getFilter
en RecyclerViewAdapterpublic Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { final FilterResults oReturn = new FilterResults(); final List<BaseOfCards> results = new ArrayList<BaseOfCards>(); if (orig == null) orig = items; if (constraint != null){ if(orig !=null & orig.size()>0 ){ for ( final BaseOfCards g :orig) { if (g.getCardName().toLowerCase().contains(constraint.toString()))results.add(g); } } oReturn.values = results; } return oReturn; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { items = (ArrayList<BaseOfCards>)results.values; notifyDataSetChanged(); } };
-
Make MainActivity
implements SearchView.OnQueryTextListener
SearchView.OnQueryTextListener y cambia el métodoonQueryTextChange
:@Override public boolean onQueryTextChange(String newText) { if ( TextUtils.isEmpty ( newText ) ) { adapter.getFilter().filter(""); } else { adapter.getFilter().filter(newText.toString()); } return true; }
Utilizando un autocompletetextview o un edittext i manejó éste como siguiente donde
public List<SalesProductsItems> mItems
Es la instancia listitem inicial y.
public static List<SalesProductsItems> filteredIt
Es la instancia utilizada en la visualización de items.Since la primera vez que los resultados del filtro no es null la instancia de mItems
será igual a la instancia de mItems
(por lo tanto perder la lista inicial), luego en el método publishResults
justo antes mItems
pierde los valores originales, M equivalente a la instancia pasada originallist
. Espero que ayude a alguien
private static class ProductsFilter extends Filter { private final SalesProductsAdapter adapter; private final List<SalesProductsItems> originalList; private final List<SalesProductsItems> filteredList; private ProductsFilter(SalesProductsAdapter adapter, List<SalesProductsItems> originalList) { super(); this.adapter = adapter; this.originalList = new LinkedList<>(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(); for (final SalesProductsItems it : originalList) { if (it.getProduct().toLowerCase().contains(filterPattern)) { filteredList.add(it); } } } results.values = filteredList; results.count = filteredList.size(); return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { adapter.mItems = originalList; if(results.count > 0) { filteredIt.clear(); filteredIt.addAll((ArrayList<SalesProductsItems>) results.values); adapter.notifyDataSetChanged(); } else { filteredIt.clear(); filteredIt.addAll(adapter.mItems); adapter.notifyDataSetChanged(); } } }
Quiero añadir a la respuesta ololoking . En MainActivity
también debemos añadir el siguiente código para que funcione:
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_layout, menu); MenuItem searchItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); searchView.setIconifiedByDefault(true); searchView.setOnQueryTextListener(this); return super.onCreateOptionsMenu(menu); }
Gracias ololoking por su respuesta. Me ayudó.
Desde el momento en que se realizó la otra respuesta positiva, ahora he implementado un filtro asíncrono rápido usando AsyncTask
en mi biblioteca FlexibleAdapter , el rendimiento es muy bueno con listas grandes, con animaciones también! El adaptador es configurable para activar / desactivar las propiedades en el resultado de filtrado para aumentar la velocidad cuando sea necesario. Otra gran ventaja es que la interfaz sigue respondiendo al usuario.
Prueba hecha en mi Samsung S3 con Android 6: con una lista inicial de 10.450 elementos, desde el momento en que comienza el proceso de fondo toma ~ 1s para filtrar un carácter y seleccionar 3.890 elementos.
También he hecho una página Wiki con todos los detalles para usar el filtro con el adaptador.
- Cómo establecer el contenido en un diseño lineal a la parte inferior de la pantalla en Android.
- Cómo implementar google + listview animación