我正在寻找一种方法来过滤 RecyclerView 中的数据,而在应用过滤器时,给定 View 的状态不会影响另一个 View 。实际上,我有这个问题: 1. 我通过单击添加按钮将“Martins”添加到我的 friend 列表中(图片 msSxq.png) 不带过滤器的列表
很明显,随着搜索操作完成,我的列表内容发生变化,然后新项目取代旧项目并采用旧项目按钮状态!
我正在寻找一种方法来避免这种情况。我尝试阅读几篇有关类似主题的文章,但一无所获(链接示例:How to filter a RecyclerView with a SearchView)
感谢您的帮助!
编辑:07/02/2020 - onBindViewHolder 和过滤代码
onBindViewHolder(在我的自定义适配器中)
@Override
public void onBindViewHolder(@NonNull final FriendAdapterViewHolder holder, int position) {
String mUsernameString = suggestionList.get(position);
String mModUsernameString = suggestionList.get(position) + "_@chatter";
holder.username.setText(mUsernameString);
holder.mod_username.setText(mModUsernameString);
}
过滤方法(始终在我的适配器中)
@Override
public Filter getFilter() {
return friendFilter;
}
private Filter friendFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<String> listFiltered = new ArrayList<>();
if (fullSuggestionList != null) {
if (constraint == null || constraint.length() == 0) {
listFiltered.addAll(fullSuggestionList);
} else {
String searchTextLowerCase = constraint.toString().toLowerCase().trim();
for (String item : fullSuggestionList) {
if (item.toLowerCase().contains(searchTextLowerCase)) {
listFiltered.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = listFiltered;
return results;
} else {
return null;
}
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results.values != null) {
suggestionList.clear();
suggestionList.addAll((ArrayList<String>) results.values);
notifyDataSetChanged();
}
}
};
最后,在我执行搜索操作的 Activity 中
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if (adapter.getCompleteItemList() != null) {
adapter.getFilter().filter(newText);
}
return false;
}
});
最佳答案
最后,我尝试深入了解recyclerview的工作原理,并找到了一个完美的解决方案。事实上,当我们在链接到回收器 View 的搜索 View 中过滤数据时,最后一个 View (当不需要时)会回收已创建的 View 并仅更改其内容。为了避免这种情况,我们必须为创建的每个 View 创建一个唯一的标识符,并告诉我们的 recyclerview 有唯一的 View ID。实际上,我做了这些事情:
在我的数据模型中,我创建了一个方法,为创建的每个实例生成一个唯一的 ID,如下所示:
public class MyDataModel {
private long mId;
...//others variables here
private long computeId(.../*some parameters if needed*/) {
// write code here to generate your unique code
return result;
}
public long getmId() {
return this.mId;
}
然后,在我的适配器中,我重写 getItemId() 方法
@override public long getItemId(int position) {
return myDataList.get(position).getmId();
}
而且,总是在我的适配器中,在其构造函数中我添加这行代码:
this.setHasStableIds(true);
仅此而已!
关于java - 管理 RecyclerView 中 View 的回收方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60096452/