Agregar un filtro de búsqueda en RecyclerView con tarjetas?

Encontré soluciones para los filtros en ListView y SearchView en RecyclerView separado, pero deseo combinarlos. ¿Es posible?

Sí, es posible que su RecyclerView.Adapter pueda implementar Filterable . Después de eso, debes anular el Filter getFilter() .

Debe definir su propio filtro como se muestra en el siguiente código:

 @Override public Filter getFilter() { return new YourFilterClass(); } 

YourFilterClass

 class YourFilterClass extends Filter { @Override protected FilterResults performFiltering(CharSequence constraint) { //Here you have to implement filtering way final FilterResults results = new FilterResults(); //logic to filtering results.values = ... results.count = ... return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { // here you can use result - (fe set in in adapter list) } } 

Ejemplo

 public class UserListAdapter extends RecyclerView.Adapter implements Filterable { private final List userList; private final List filteredUserList; private UserFilter userFilter; public UserListAdapter(Context context) { this.userList =new ArrayList<>(); this.filteredUserList = new ArrayList<>(); } ///... other methods @Override public Filter getFilter() { if(userFilter == null) userFilter = new UserFilter(this, userList); return userFilter; } private static class UserFilter extends Filter { private final UserListAdapter adapter; private final List originalList; private final List filteredList; private UserFilter(UserListAdapter adapter, List 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.length() == 0) { filteredList.addAll(originalList); } else { final String filterPattern = constraint.toString().toLowerCase().trim(); for (final User user : originalList) { if (user.getName().contains(filterPattern)) { filteredList.add(user); } } } results.values = filteredList; results.count = filteredList.size(); return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { adapter.filteredUserList.clear(); adapter.filteredUserList.addAll((ArrayList) results.values); adapter.notifyDataSetChanged(); } } } 

Después de eso, en el lugar en el que desea filtrar la llamada:

 userListAdapter.getFilter().filter(text) 

Dentro de Fragment Class declara que:

 protected List mDataset; protected List mDataOrigin; 

luego, dentro onCreate agrega el mismo destino de origen a dataSet y a dataOrigin

 mDataset = getObjectsFromDB(); mDataOrigin = getObjectsFromDB(); 

Finalmente usa la función mágica:

 private void filterRecyclerView(String charText){ charText = charText.toLowerCase(); clearDataSet(); if (charText.length() == 0) { mDataset.addAll(mDataOrigin); } else { for (User user : mDataOrigin) { if (user.getName().toLowerCase().contains(charText)) { mDataset.add(user); } } } mAdapter.notifyDataSetChanged(); } 

Aviso El User es el contenido de la lista que puede reemplazar con su objeto diviértase 🙂

Aquí hay un código de muestra completo

Clase de modelo

 public class Skills { int id; String skill; boolean isSelected; public boolean isSelected() { return isSelected; } public void setSelected(boolean selected) { isSelected = selected; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getSkill() { return skill; } public void setSkill(String skill) { this.skill = skill; } } 

Clase de adaptador

 private static final String TAG = SkillAdapter.class.getSimpleName(); protected List mOriginalData = new ArrayList<>(); protected List mResultData = new ArrayList<>(); protected Activity mActivity; OnRecyclerViewClick onRecyclerViewClick; private ItemFilter mFilter = new ItemFilter(); public SkillAdapter(Activity activity, OnRecyclerViewClick onRecyclerViewClick) { mActivity = activity; this.onRecyclerViewClick = onRecyclerViewClick; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_skill, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { final Skills data = mResultData.get(position); try { final ViewHolder viewHolder = (ViewHolder) holder; if (data != null) { viewHolder.checkSkill.setText(data.getSkill()); viewHolder.checkSkill.setChecked(data.isSelected()); } } catch (Exception e) { e.printStackTrace(); } } @Override public int getItemCount() { return mResultData.size(); } public void addItem(Skills exam) { mOriginalData.add(exam); mResultData.add(exam); int index = mOriginalData.indexOf(exam); notifyItemInserted(index); } public void removeItem(int index) { mOriginalData.remove(index); notifyItemRemoved(index); } public void removeItem(Skills exam) { int index = mOriginalData.indexOf(exam); mOriginalData.remove(exam); notifyItemRemoved(index); } public Filter getFilter() { return mFilter; } public Skills getItem(int index) { return mOriginalData.get(index); } public void replaceItem(int index, Skills audioMeta) { mOriginalData.set(index, audioMeta); notifyItemChanged(index); } public class ViewHolder extends RecyclerView.ViewHolder { CheckBox checkSkill; public ViewHolder(View itemView) { super(itemView); checkSkill = (CheckBox) itemView.findViewById(R.id.chkSkill); checkSkill.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onRecyclerViewClick.onItemClick(v, getLayoutPosition()); } }); } } private class ItemFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence constraint) { String filterString = constraint.toString().toLowerCase(); FilterResults results = new FilterResults(); int count = mOriginalData.size(); final ArrayList tempFilterList = new ArrayList(count); String filterableString; for (int i = 0; i < count; i++) { filterableString = mOriginalData.get(i).getSkill(); if (filterableString.toLowerCase().contains(filterString)) { tempFilterList.add(mOriginalData.get(i)); } } results.values = tempFilterList; results.count = tempFilterList.size(); return results; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint, FilterResults results) { mResultData.clear(); mResultData = (ArrayList) results.values; notifyDataSetChanged(); } } 

En uso de la actividad

  mAdapter = new SkillAdapter(SkillsActivity.this, SkillsActivity.this); recyclerView.setLayoutManager(new LinearLayoutManager(mContext)); recyclerView.setAdapter(mAdapter); 

Luego filtro

 editSearch.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) { } @Override public void afterTextChanged(Editable s) { mAdapter.getFilter().filter(editSearch.getText().toString()); } });