RecyclerView更改数据集

我想为我的RecyclerView实现searchfunction。 在文字改变,我想改变与这个小部件显示的数据。 也许这个问题之前已经被问过或很简单,但我不知道如何改变要显示的数据…

我的RecyclerView定义如下:

// 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") }; 

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

Solutions Collecting From Web of "RecyclerView更改数据集"

如果在适配器中有稳定的ID,如果创build一个包含已过滤项目的新数组并调用,则可以获得相当好的结果(animation)

 recyclerView.swapAdapter(newAdapter, false); 

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

一个更好的方法是find哪些项目被删除,并调用notifyItemRemoved(index) 。 不要忘记实际移除物品。 这将使RecyclerView运行预测animation。 假设你有一个内部使用ArrayList的Adapter,实现如下所示:

 // 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 ,它将执行得更好。 它会看起来像:(未testing)

 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); } } 

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

请记住,每个通知项目调用都会影响后面的项目(这就是为什么我从最后遍历列表来避免它)。 从最后遍历也有助于ArrayList的删除方法的性能(更less的项目转移)。

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

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

或者如果你一个一个发送

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

这是我的答案 – 感谢来自他的网站的Ivan Skoric: http : //blog.lovelyhq.com/creating-lists-with-recyclerview-in-android/

我在适配器类中创build了一个额外的方法:

 public void updateList(List<Data> data) { mData = data; notifyDataSetChanged(); } 

然后每次数据更改时,只需调用此方法传递新数据,并且您的视图应该更改以反映它。

只需重新初始化您的适配器:

mAdapter = new ItemsAdapter(newItemsData);

或者如果你只需要删除添加一些特定的项目,而不是整个列表:

mAdapter。 notifyItemInserted(位置);

要么

mAdapter.notiftyItemRemoved(位置);

正如ygit回答的那样, swapAdapter是很有趣的,当你必须改变整个内容。

但是,在我的FlexibleAdapter中,您可以使用updateDataSet更新项目。 您甚至可以将适配器configuration为调用notifyDataSetChanged或具有同步animation(默认情况下启用)。 那是因为notifyDataSetChanged杀死了所有的animation,但是对于大列表来说是很好的select。

请查看描述,demoApp和Wiki页面: https : //github.com/davideas/FlexibleAdapter