在RecyclerView上添加searchfilter?
我在RecyclerView
ListView
和SearchView
上分别find了filter的解决scheme,但我希望将它们结合起来。 这甚至有可能吗?
是的,您的RecyclerView.Adapter
可以实现Filterable
。 之后,你必须重写Filter getFilter()
方法。
你必须定义你自己的filter,如下面的代码所示:
@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) } }
例
public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.ViewHolder> implements Filterable { private final List<User> userList; private final List<User> 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<User> originalList; private final List<User> filteredList; private UserFilter(UserListAdapter adapter, List<User> 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<User>) results.values); adapter.notifyDataSetChanged(); } } }
之后,在你想要过滤的地方调用:
userListAdapter.getFilter().filter(text)
内部Fragment Class
声明:
protected List<User> mDataset; protected List<User> mDataOrigin;
然后在onCreate
添加相同的源目标数据集antdataOrigin
mDataset = getObjectsFromDB(); mDataOrigin = getObjectsFromDB();
最后使用魔术function:
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(); }
注意User
是你可以用你的对象取代的列表内容有乐趣:)
这里是完整的示例代码
模型类
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; } }
适配器类
private static final String TAG = SkillAdapter.class.getSimpleName(); protected List<Skills> mOriginalData = new ArrayList<>(); protected List<Skills> 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<Skills> tempFilterList = new ArrayList<Skills>(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<Skills>) results.values; notifyDataSetChanged(); } }
在活动中使用
mAdapter = new SkillAdapter(SkillsActivity.this, SkillsActivity.this); recyclerView.setLayoutManager(new LinearLayoutManager(mContext)); recyclerView.setAdapter(mAdapter);
然后过滤
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()); } });