Android RecyclerView 更改数据集
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26635841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
RecyclerView change data set
提问by Sandra
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:
我的 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);
And the data that I am showing is something like:
我显示的数据类似于:
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?
所以当我想给适配器另一组数据,另一个数组(例如一个项目)时,我该怎么办?
回答by yigit
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
如果您的适配器中有稳定的 id,如果您创建一个包含过滤项目的新数组并调用,您可以获得相当不错的结果(动画)
recyclerView.swapAdapter(newAdapter, false);
Using swapAdapterhints 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).
使用swapAdapter提示 RecyclerView 它可以重用视图持有者。(与 setAdapter 相比,它必须回收所有视图并重新创建,因为它不知道新适配器与旧适配器具有相同的 ViewHolder 集)。
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:
更好的方法是找到哪些项目被删除并调用notifyItemRemoved(index)
. 不要忘记实际删除该项目。这将使 RecyclerView 运行预测动画。假设您有一个内部使用 ArrayList 的适配器,实现将如下所示:
// 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);
}
}
}
It would perform even better if you can batch notifyItemRemoved
calls and use notifyItemRangeRemoved
instead. It would look sth like: (not tested)
如果您可以批量notifyItemRemoved
调用并notifyItemRangeRemoved
改为使用,它的性能会更好。它看起来像:(未测试)
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.
您需要扩展此代码以添加以前被过滤掉但现在应该可见的项目(例如用户删除过滤器查询),但我认为这应该给出基本的想法。
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).
请记住,每个通知项调用都会影响它之后的项(这就是我从末尾遍历列表以避免它的原因)。从末尾遍历还有助于 ArrayList 的 remove 方法性能(更少的项目需要移动)。
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
回答by Simon
This is my answer - thanks to Ivan Skoric from his site: http://blog.lovelyhq.com/creating-lists-with-recyclerview-in-android/
这是我的回答 - 感谢 Ivan Skoric 从他的网站:http: //blog.lovelyhq.com/creating-lists-with-recyclerview-in-android/
I created an extra method inside my adapter class:
我在适配器类中创建了一个额外的方法:
public void updateList(List<Data> data) {
mData = data;
notifyDataSetChanged();
}
Then each time your data changes, you just call this method passing in your new data and your view should change to reflect it.
然后每次您的数据更改时,您只需调用此方法传入您的新数据,您的视图应该更改以反映它。
回答by Chad Bingham
Just re-initialize your adapter:
只需重新初始化您的适配器:
mAdapter = new ItemsAdapter(newItemsData);
or if you only need to remove add a few specific items rather than a whole list:
或者如果您只需要删除添加一些特定项目而不是整个列表:
mAdapter.notifyItemInserted(position);
or
或者
mAdapter.notifyItemRemoved(position);
回答by Ebad Ali
If you want to change the complete Adapter in the recycler view. you can just simply set by recycler.setAdapter(myAdapter);
It will automatically remove the old adapter from recycler view and replace it with your new adapter.
如果要在回收站视图中更改完整的适配器。您可以简单地通过设置recycler.setAdapter(myAdapter);
它会自动从回收站视图中删除旧适配器并将其替换为您的新适配器。
回答by Davideas
As ygitanswered, swapAdapter
is interesting when you have to change the whole content.
正如ygit回答的那样,swapAdapter
当您必须更改整个内容时很有趣。
But, in my FlexibleAdapter, you can update the items with updateDataSet
. You can even configure the adapter to call notifyDataSetChanged
or having synchronization animations (enabled by default). That, because notifyDataSetChanged kills all the animations, but it's good to have for big lists.
但是,在我的 FlexibleAdapter 中,您可以使用updateDataSet
. 您甚至可以将适配器配置为调用notifyDataSetChanged
或具有同步动画(默认启用)。那是因为 notifyDataSetChanged 会杀死所有动画,但对于大列表来说是很好的。
Please have a look at the description, demoApp and Wiki pages: https://github.com/davideas/FlexibleAdapter
请查看说明、demoApp 和 Wiki 页面:https: //github.com/davideas/FlexibleAdapter