【问题标题】:Manage how views are recycled in RecyclerView在 RecyclerView 中管理视图的回收方式
【发布时间】:2020-02-12 22:21:51
【问题描述】:

我正在寻找一种方法来过滤 RecyclerView 中的数据,而在应用过滤器时,给定视图的状态不会影响另一个视图。实际上,我有这个问题: 1.我通过点击添加按钮将“Martins”添加到我的朋友列表中(图片 msSxq.png) 没有过滤器的列表

  1. 我执行了一次搜索,我得到了这个(图片 FGSwF.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;
        }
    });

【问题讨论】:

  • OnBindViewHolder发布您的代码和您的搜索代码
  • @COYG 我刚刚更新了帖子!

标签: java android android-recyclerview


【解决方案1】:

最后,我尝试深入了解 recyclerview 的工作原理,并找到了一个完美的解决方案。事实上,当我们在链接到回收视图的搜索视图中过滤数据时,最后一个在不需要时,会回收已经创建的视图并简单地更改其内容。为了避免这种情况,我们必须为创建的每个视图创建一个唯一标识符,并告诉我们的 recyclerview 具有唯一的视图 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);

就是这样!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    相关资源
    最近更新 更多