Ich habe Lösungen für Filter in ListView
und SearchView
in RecyclerView
separat gefunden, aber ich möchte sie kombinieren. Ist es überhaupt möglich?
Ja, es ist möglich, dass Ihr RecyclerView.Adapter
Filterable
implementieren kann. Danach müssen Sie die Filter getFilter()
Methode überschreiben.
Sie müssen Ihren eigenen Filter definieren, wie im folgenden Code gezeigt:
@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 - (f.e. 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();
}
}
}
Danach an der Stelle, an der Sie den Anruf filtern möchten:
userListAdapter.getFilter().filter(text)
Innerhalb Fragment Class
erklären, dass:
protected List<User> mDataset;
protected List<User> mDataOrigin;
fügen Sie dann innerhalb von onCreate
dasselbe Quellenziel zu beiden dataSet und dataOrigin hinzu
mDataset = getObjectsFromDB();
mDataOrigin = getObjectsFromDB();
Verwenden Sie zum Schluss die Zauberfunktion:
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();
}
Hinweis User
ist der Listeninhalt, den Sie durch Ihr Objekt ersetzen können. Viel Spaß :)
Hier ist der vollständige Beispielcode
Modellklasse
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;
}
}
Adapterklasse
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();
}
}
in Verwendung
mAdapter = new SkillAdapter(SkillsActivity.this, SkillsActivity.this);
recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
recyclerView.setAdapter(mAdapter);
Dann Filter
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());
}
});