在ArrayAdapter<T>
子类上使用自定义过滤器时,在显示之前,我总是最终让容器ListView
在运行时显示所有元素,只需几分之一秒实际过滤的清单。
当用户使用SearchView
/ TextView
进行过滤时,这尤其会损害用户体验,并且需要调用过滤器事件onQueryTextChange
,这样过滤器似乎会在每次按键时重置
我的实现通常是这样的:
public class FilterAdapter extends ArrayAdapter<ListElement> {
private Context mContext;
public List<ListElement> listElements;
...
@Override
public Filter getFilter(){
return new Filter(){
@Override
protected FilterResults performFiltering(CharSequence constraint) {
Locale currentLocale = mContext.getResources().getConfiguration().locale;
constraint = constraint.toString().toLowerCase(currentLocale);
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
//get a COPY of the original elements array not to change it by reference
results.values = new ArrayList<ListElement>(FilterAdapter.this.listElements);
results.count = listElements.size();
}
else{
List<ListElement> found = new ArrayList<ListElement>();
for(ListElement item : FilterAdapter.this.listElements){
if(item.filterString().toLowerCase(currentLocale).contains(constraint)){
found.add(item); //no need to create a copy of single element
}
}
results.values = found;
results.count = found.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
clear();
for (ListElement item : (List<ListElement>) results.values) {
add(item);
}
notifyDataSetChanged();
}
};
}
根据我的理解,Filter.performFiltering
子类AsyncTask
(或者至少在自己的线程中运行,从未真正去过AOSP进行检查),Filter.publishResults
只是UI的处理程序适配器的线程。
我看到过滤器的每个实现都倾向于在publishResults的开头和结尾调用ArrayList.clear()
和ArrayList.notifyDataSetChanged
,并且我没有过滤器在没有明确的+通知的情况下工作...,尽管我和#39 ;很漂亮
是否有任何提示可以删除第二次重置的那一部分,并且只需一次从一个过滤列表转到另一个?
答案 0 :(得分:0)
尝试将此android:scrollingCache="false"
添加到布局文件中的<ListView>
元素中。
答案 1 :(得分:0)
我实际上在询问了5m之后偶然发现了一个解决方案,同时解决了一个糟糕的getCount()问题:问题是同步,因为最初被怀疑。我这样称呼过滤器......
auxAdapter.getFilter().filter(currentUserTextFilter);
//and sequentially I replaced the old adapter on the list
contactsAdapter = auxAdapter;
listViewContacts.setAdapter(contactsAdapter);
//...bunch of other operations in between, and then...
Log.i(activityName, "Item count: " + listViewContacts.getAdapter().getCount());
...并且.filter(String constraint)
没有阻止并且实际上花费的时间比设置新适配器要长,所以它显示了一个完整的列表,并且还让我意外(但正确)项目计数(当我实际调试那个计数时)。
工作代码使用filter(CharSequence constraint, Filter.FilterListener listener)
而不是仅限制约的版本:
auxAdapter.getFilter().filter(currentUserTextFilter, new Filter.FilterListener() {
public void onFilterComplete(int count) {
contactsAdapter = auxAdapter;
contactsAdapter.setNotifyOnChange(true);
listViewContacts.setAdapter(contactsAdapter);
updateTitle();
}
});