我想为我的RecyclerView实现搜索功能。在文本更改后,我想更改使用此小部件显示的数据。也许这个问题之前已被问过或很简单,但我不知道如何更改要显示的数据......
我的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")
};
所以当我想给适配器另一组数据,另一个数组(例如一个项目)时,我该怎么办?
答案 0 :(得分:87)
如果您的适配器中有稳定的ID,如果您创建一个包含已过滤项目的新数组并调用
,则可以获得相当不错的结果(动画)recyclerView.swapAdapter(newAdapter, false);
使用swapAdapter提示RecyclerView可以重复使用视图持有者。 (在setAdapter中,它必须回收所有视图并重新创建,因为它不知道新适配器与旧适配器具有相同的ViewHolder)。
更好的方法是找出哪些项目被移除并调用notifyItemRemoved(index)
。不要忘记实际删除该项目。这将让RecyclerView运行预测动画。假设您有一个内部使用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
,那么效果会更好。它看起来像:(未经测试)
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);
}
}
您需要扩展此代码以添加先前已过滤但现在应该可见的项目(例如,用户删除过滤器查询),但我认为这应该提供基本想法。
请记住,每个通知项目调用都会影响其后面的调用(这就是为什么我从末尾遍历列表以避免它)。从末尾遍历也有助于ArrayList删除方法性能(更少的项目移位)。
例如,如果您从头开始遍历列表并删除前两个项目。 你应该打电话
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
答案 1 :(得分:25)
这是我的答案 - 感谢Ivan Skoric来自他的网站:http://blog.lovelyhq.com/creating-lists-with-recyclerview-in-android/
我在我的适配器类中创建了一个额外的方法:
public void updateList(List<Data> data) {
mData = data;
notifyDataSetChanged();
}
然后,每次数据更改时,您只需调用此方法传入新数据,您的视图就会更改以反映它。
答案 2 :(得分:3)
只需重新初始化适配器:
mAdapter = new ItemsAdapter(newItemsData);
或者如果您只需删除添加一些特定项目而不是整个列表:
mAdapter.notifyItemInserted(position);
或
mAdapter.notifyItemRemoved(position);
答案 3 :(得分:1)
如果要在回收者视图中更改完整的适配器。您只需通过recycler.setAdapter(myAdapter);
进行设置
它将自动从回收者视图中删除旧适配器,并将其替换为新适配器。
答案 4 :(得分:0)
当 ygit 回答时,swapAdapter
在您需要更改整个内容时很有意思。
但是,在我的FlexibleAdapter中,您可以使用updateDataSet
更新项目。您甚至可以将适配器配置为调用notifyDataSetChanged
或具有同步动画(默认情况下启用)。因为notifyDataSetChanged会杀死所有动画,但是对于大型列表来说这很好。
请查看说明,demoApp和Wiki页面:https://github.com/davideas/FlexibleAdapter