DesarrolloLibre

Desarrollo Web, Android y mucho más

15-08-2016

En esta entrada veremos cómo crear un filtro para nuestros RecycleView; en una entrada anterior vimos cómo crear listados a través de listas y grids con el RecycleView hoy veremos el mismo proceso pero con un extra el cual consiste en crear un filtro para el listado anterior a través (lógicamente) por un campo de búsqueda con un simple EditText.

En nuestro adaptador crearemos una clase extra que llamaremos CustomFilter que lucirá de la siguiente manera:

public class CustomFilter extends Filter {
        private ListAdapter listAdapter;

        private CustomFilter(ListAdapter listAdapter) {
            super();
            this.listAdapter = listAdapter;
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            personsFilter.clear();
            final FilterResults results = new FilterResults();
            if (constraint.length() == 0) {
                personsFilter.addAll(persons);
            } else {
                final String filterPattern = constraint.toString().toLowerCase().trim();
                for (final Person person : persons) {
                    if (person.getName().toLowerCase().contains(filterPattern)) {
                        personsFilter.add(person);
                    }
                }
            }
            results.values = personsFilter;
            results.count = personsFilter.size();
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            this.listAdapter.notifyDataSetChanged();
        }
    }

Además de agregar un implements para implementar la clase Filterable en nuestro Adapter:

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> implements Filterable {
    private ArrayList<Person> persons;
    private ArrayList<Person> personsFilter;
    private CustomFilter mFilter;
...
}
public ListAdapter(ArrayList persons) {

    this.persons = persons;
    this.personsFilter = new ArrayList<>();
    this.personsFilter.addAll(persons);
    this.mFilter = new CustomFilter(ListAdapter.this);
}

En nuestro adaptador y el método asociado getFilter que sobreescribimos:

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

Un pequeño dato que tenemos que hacer en nuestro adaptador es crear otra lista la cual contiene la data filtrada por el usuario y otro listado que contiene el total de la data que conforma nuestro listado sin aplicar ningún filtro; teniendo esto en cuenta nuestra el constructor y así como otros métodos de control quedaran definidos de la siguiente manera:

// Constructor
public ListAdapter(ArrayList persons) {

	this.persons = persons;
	this.personsFilter = new ArrayList<>();
	this.personsFilter.addAll(persons);
	this.mFilter = new CustomFilter(ListAdapter.this);
}
...
@Override
public int getItemCount() {
	return personsFilter.size();
}
...
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
	viewHolder.nameTextView.setText(personsFilter.get(position).getName());
	viewHolder.descriptionTextView.setText(personsFilter.get(position).getDescription());
	viewHolder.colorLl.setBackgroundColor(Color.parseColor(personsFilter.get(position).getColor()));
}

Cómo ves empleamos el ArrayList filtrable en vez del ArrayList completo.

Tenemos listo el adaptador, ahora falta configurar en nuestra actividad o fragment el campo de búsqueda para poder filtrar nuestro listado y los eventos asociados; para ello emplearemos un EditText como comentamos anteriormente:

etSearchBox = (EditText) findViewById(R.id.etSearchBox);

Y el evento escuchador (listener) que se activa al ingresar/remover texto sobre el mismo:

        etSearchBox.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                listAdapter.getFilter().filter(s.toString());
            }
            @Override
            public void afterTextChanged(Editable s) {
            }
        });

Cómo puedes ver, al cambiar el texto se invoca el método filter pasando como parámetro el texto a filtrar.

Dato adicional

Puedes especificar el funcionamiento del filtro en la clase CustomFilter del adaptador definiendo el comportamiento en el momento en el que se realiza el llenado de personsFilter al realizar la comparación:

if (person.getName().toLowerCase().contains(filterPattern))

En nuestro caso nos interesa que NO sea sensible a mayúsculas/minúsculas y que contenga (contains) la palabra o sección clave y de esta forma tener un filtro bastante flexible, pero puedes expresarlo como desees.

Ayúdanos a seguir creciendo

Publicidad

Give me for a beer!

Algunos recursos que te pueden interesar

Paleta de colores para el Material Design

Paleta de colores para el Material Design

Creando increibles Drawer en Android con MaterialDrawer

Creando increibles Drawer en Android con MaterialDrawer

Librería oficial de PayPal para Android

Librería oficial de PayPal  para Android

Algunos artículos que te pueden interesar

Desarrollando aplicaciones de Realidad aumentada con Wikitude (parte 1)

Desarrollando aplicaciones de Realidad aumentada con Wikitude (parte 1)

En esta primera entrega veremos como configurar nuestro proyecto Android para comenzar a utilizar esta librería de realidad aumentada, para esto utilizaremos eclipse y el plugin ADT.

Andrés Cruz 26-09-2013

Los diálogos (dialogs) en Android

Los diálogos (dialogs) en Android

Los diálogos (dialogs) en Android no son más que una pequeña ventana personalizables a través de estilos y layouts y en la SDK de Android cuenta con clases incorporadas; en esta entrada veremos los distintos tipos de dialogs en Android.

Andrés Cruz 10-09-2015

Como crear layouts cuadrados en Android

Como crear layouts cuadrados en Android

Se explica cómo crear un layout personalizado en Android que se cuadrado, el mismo puede ser aplicado desde vistas principales hasta grids y listados.

Andrés Cruz 18-07-2016