当在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线程的一个处理程序。
我看到的过滤器的每一个实现都倾向于在ArrayList.clear()和ArrayList.notifyDataSetChanged开始和结束时调用publishResults,而且我从来没有在没有clear+notify的情况下使用过滤器.尽管我很漂亮
删除第二次重置的那一小部分,然后一次从一个过滤列表转到另一个筛选列表,有什么建议吗?
发布于 2014-04-02 15:58:08
尝试将此android:scrollingCache="false"添加到布局文件中的<ListView>元素中。
发布于 2014-04-02 16:18:22
实际上,我在询问之后偶然发现了一个解决方案500万,同时解决了一个糟糕的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());...and .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();
}
});https://stackoverflow.com/questions/22816499
复制相似问题