我在Android应用上处理 InstantSearch功能,我想要实现的结果如下图所示。
除了一件事,一切都正常。我正在使用的ArrayList是BIG(它包含近400k字)。因此,我在ListView上显示我的结果时遇到了性能问题(它很多)。
我很确定这是由我的Wordlist的长度造成的,因为减少了它的字数,一切都很顺利。
以下是我在适配器类中的过滤代码:
private class SearchResultsFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<String> found = new ArrayList<>();
if (constraint != null) {
for (String word : MainActivity.WordList) {
if (word.startsWith(constraint.toString().toLowerCase())) {
found.add(word);
}
}
}
filteredList = found;
filterResults.values = found;
filterResults.count = found.size();
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults filterResults) {
if (filterResults.count > 0) {
Log.println(Log.INFO, "Results", "FOUND");
results.clear();
results.addAll((ArrayList<String>) filterResults.values);
notifyDataSetChanged();
} else {
Log.println(Log.INFO, "Results", "-");
results.clear();
notifyDataSetInvalidated();
}
}
}
这就是我在 MainActivity :
中加载ArrayList的方法public static void loadDictionary(Activity activity) {
//loading wordslist from file.
BufferedReader line_reader = new BufferedReader(new InputStreamReader(activity.getResources().openRawResource(R.raw.wordlist)));
String line;
try {
while ((line = line_reader.readLine()) != null) {
WordList.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
Collections.sort(WordList);
谢谢大家,
度过愉快的一天。
答案 0 :(得分:1)
我是Cesarsk项目的合作者,我注意到我们的问题是 performFiltering 方法。我们使用的Wordlist中有394.000+个元素,每次用户在SearchBar的EditText中键入一个字母时,performFiltering方法都会检查所有这些元素,即使它应该在每次迭代中排除一些。所以我实现了一种简单的方法来将列表拆分为不同的子列表。每个列表仅包含以字母表中的单个字母开头的单词。
意义:
列表2仅包含以字母“ b ”
开头的单词依旧......
然后我将所有列表放在 HashMap 中,其中 key =字母。这样做,现在我们只能选择与用户键入的第一个字母匹配的子列表,循环检查的字数少得多,立即产生结果。
以下是一些代码:
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<Pair<String, String>> temp_list = null;
ArrayList<Pair<String, String>> found = new ArrayList<>();
if (constraint != null) {
if (!(constraint.toString().isEmpty())) {
temp_list = MainActivity.Wordlists_Map.get(constraint.toString().substring(0,1).toLowerCase());
if(temp_list != null){
for(Pair<String, String> element : temp_list){
if(element.first.startsWith(constraint.toString().toLowerCase())){
found.add(element);
}
}
}
}
}
filterResults.values = found;
filterResults.count = found.size();
return filterResults;
}