如何搜索 RecyclerView 中显示的对象列表?
How to search a list of Objects that are displayed in a RecyclerView?
我目前正在尝试实现 SearchView,但显示的搜索结果仅在第一次搜索时发生变化,我在 SearchView 中输入的所有其他内容都将被忽略。
这是我在 MainActivity.java
:
中的搜索代码
testList = Arrays.asList(new TestItem("aw"), new TestItem("aa"), new TestItem("w"));
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.test_menu, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setOnQueryTextListener(this);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onQueryTextChange(String newText) {
List<TestItem> result = new ArrayList<>();
for(TestItem t: testList) {
if(t.getName().contains(newText) {
result.add(t);
}
}
adapter.changeList(result);
return true;
}
adapter.changeList:
public void changeList(List<TestItem> newList) {
this.list = new ArrayList<>(newList);
}
onQueryTextChange 在每次文本更改后调用,但搜索结果只显示一次。输入 a
和 Enter
时,RecyclerView 显示 aw
和 aa
(必须按 Enter 才能启动 onQueryTextChange
是否正常?),但是当我然后输入 aa
显示的项目保持不变。
我认为你的实现不正确。您无需按回车键即可获得搜索结果。为了实现,您可以保留数组的完整副本 list.Then 制作另一个临时列表形式,当查询文本更改时列出该列表。所以当您过滤时,您搜索的是实际列表而不是过滤后的列表。
1.pass 搜索关键字到列表适配器
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return true;
}
2。在适配器中实现 Filterable 和覆盖方法
@Override
public Filter getFilter() {
if (frameFilter == null) {
frameFilter = new FrameFilter();
}
return frameFilter;
}
3。过滤 class 可以是这样的:'categoryMain' 是我的完整列表,'categoryTemp' 是我的临时列表
private class FrameFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<Category> tempList = new ArrayList<>();
// search content in friend list
Log.i("key",constraint.toString());
for (Category category : categoriesMain) {
if (category.getCategory_name().toLowerCase().contains(constraint.toString().toLowerCase())) {
tempList.add(category);
}
}
filterResults.count = tempList.size();
filterResults.values = tempList;
} else {
filterResults.count = categoriesMain.size();
filterResults.values = categoriesMain.clone();
}
return filterResults;
}
/**
* Notify about filtered list to ui
*
* @param constraint text
* @param results filtered result
*/
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
categoriesTemp = (ArrayList<Category>) results.values;
notifyDataSetChanged();
}
}
我目前正在尝试实现 SearchView,但显示的搜索结果仅在第一次搜索时发生变化,我在 SearchView 中输入的所有其他内容都将被忽略。
这是我在 MainActivity.java
:
testList = Arrays.asList(new TestItem("aw"), new TestItem("aa"), new TestItem("w"));
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.test_menu, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setOnQueryTextListener(this);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onQueryTextChange(String newText) {
List<TestItem> result = new ArrayList<>();
for(TestItem t: testList) {
if(t.getName().contains(newText) {
result.add(t);
}
}
adapter.changeList(result);
return true;
}
adapter.changeList:
public void changeList(List<TestItem> newList) {
this.list = new ArrayList<>(newList);
}
onQueryTextChange 在每次文本更改后调用,但搜索结果只显示一次。输入 a
和 Enter
时,RecyclerView 显示 aw
和 aa
(必须按 Enter 才能启动 onQueryTextChange
是否正常?),但是当我然后输入 aa
显示的项目保持不变。
我认为你的实现不正确。您无需按回车键即可获得搜索结果。为了实现,您可以保留数组的完整副本 list.Then 制作另一个临时列表形式,当查询文本更改时列出该列表。所以当您过滤时,您搜索的是实际列表而不是过滤后的列表。
1.pass 搜索关键字到列表适配器
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return true;
}
2。在适配器中实现 Filterable 和覆盖方法
@Override
public Filter getFilter() {
if (frameFilter == null) {
frameFilter = new FrameFilter();
}
return frameFilter;
}
3。过滤 class 可以是这样的:'categoryMain' 是我的完整列表,'categoryTemp' 是我的临时列表
private class FrameFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<Category> tempList = new ArrayList<>();
// search content in friend list
Log.i("key",constraint.toString());
for (Category category : categoriesMain) {
if (category.getCategory_name().toLowerCase().contains(constraint.toString().toLowerCase())) {
tempList.add(category);
}
}
filterResults.count = tempList.size();
filterResults.values = tempList;
} else {
filterResults.count = categoriesMain.size();
filterResults.values = categoriesMain.clone();
}
return filterResults;
}
/**
* Notify about filtered list to ui
*
* @param constraint text
* @param results filtered result
*/
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
categoriesTemp = (ArrayList<Category>) results.values;
notifyDataSetChanged();
}
}