RecyclerView 更改数据集 [英] RecyclerView change data set

查看:23
本文介绍了RecyclerView 更改数据集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为我的 RecyclerView 实现搜索功能.在更改文本时,我想更改与此小部件一起显示的数据.也许这个问题以前有人问过或者很简单,但我不知道如何更改要显示的数据...

I want to implement search functionality for my RecyclerView. On text changed i want to change the data that are displayed with this widget. Maybe this question has been asked before or is simple, but I don't know how the change the data that is to be shown...

我的 RecyclerView 定义如下:

My RecyclerView is defined as follows:

     // 1. get a reference to recyclerView
    mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);

    // 2. set layoutManger
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    // 3. create an adapter
    mAdapter = new ItemsAdapter(itemsData);
    // 4. set adapter
    mRecyclerView.setAdapter(mAdapter);

我展示的数据类似于:

   ItemData itemsData[] = { new ItemData("Mary Richards"),
        new ItemData("Tom Brown"),
        new ItemData("Lucy London")          
};

所以当我想给适配器另一组数据,另一个数组(例如一个项目)时,我该怎么办?

So when when I want to give the adapter another set of data, another array (with one item for example), what should I do?

推荐答案

如果您的适配器中有稳定的 id,如果您创建一个包含过滤项的新数组并调用

If you have stable ids in your adapter, you can get pretty good results (animations) if you create a new array containing the filtered items and call

recyclerView.swapAdapter(newAdapter, false);

使用 swapAdapter 提示 RecyclerView 它可以重用视图持有者.(与 setAdapter 相比,它必须回收所有视图并重新创建,因为它不知道新适配器与旧适配器具有相同的 ViewHolder 集).

Using swapAdapter hints RecyclerView that it can re-use view holders. (vs in setAdapter, it has to recycle all views and re-create because it does not know that the new adapter has the same ViewHolder set with the old adapter).

更好的方法是找出哪些项目被删除并调用notifyItemRemoved(index).不要忘记实际删除该项目.这将使 RecyclerView 运行预测动画.假设您有一个内部使用 ArrayList 的适配器,实现将如下所示:

A better approach would be finding which items are removed and calling notifyItemRemoved(index). Don't forget to actually remove the item. This will let RecyclerView run predictive animations. Assuming you have an Adapter that internally uses an ArrayList, implementation would look like this:

// adapter code
final List<ItemData> mItems = new ArrayList(); //contains your items
public void filterOut(String filter) {
   final int size = mItems.size();
   for(int i = size - 1; i>= 0; i--) {
       if (mItems.get(i).test(filter) == false) {
           mItems.remove(i);
           notifyItemRemoved(i);
       }
   }
}

如果您可以批量调用 notifyItemRemoved 并使用 notifyItemRangeRemoved 代替,它的性能会更好.它看起来像:(未测试)

It would perform even better if you can batch notifyItemRemoved calls and use notifyItemRangeRemoved instead. It would look sth like: (not tested)

public void filterOut(String filter) {
   final int size = mItems.size();
   int batchCount = 0; // continuous # of items that are being removed
   for(int i = size - 1; i>= 0; i--) {
       if (mItems.get(i).test(filter) == false) {
           mItems.remove(i);
           batchCount ++;
       } else if (batchCount != 0) { // dispatch batch
           notifyItemRangeRemoved(i + 1, batchCount);
           batchCount = 0;
       }
   }
   // notify for remaining
   if (batchCount != 0) { // dispatch remaining
       notifyItemRangeRemoved(0, batchCount);
   }
}

您需要扩展此代码以添加以前被过滤掉但现在应该可见的项目(例如用户删除过滤器查询),但我认为这应该给出基本的想法.

You need to extend this code to add items that were previously filtered out but now should be visible (e.g. user deletes the filter query) but I think this one should give the basic idea.

请记住,每个通知项调用都会影响它之后的项(这就是我从末尾遍历列表以避免它的原因).从末尾遍历也有助于 ArrayList 的 remove 方法性能(更少的项目需要移动).

Keep in mind that, each notify item call affects the ones after it (which is why I'm traversing the list from end to avoid it). Traversing from end also helps ArrayList's remove method performance (less items to shift).

例如,如果您从头开始遍历列表并删除前两项.你应该打电话

For example, if you were traversing the list from the beginning and remove the first two items. You should either call

notifyItemRangeRemoved(0, 2); // 2 items starting from index 0

或者如果你一个一个发送

or if you dispatch them one by one

notifyItemRemoved(0);
notifyItemRemoved(0);//because after the previous one is removed, this item is at position 0

这篇关于RecyclerView 更改数据集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆