Android项目需求,要对一个ListView进行多字段模糊过滤, 系统自带的ArrayAdapter是有过滤功能,但是项目使用的是BaseAdapter适配器, List<Object>做数据源, 如果要实现过滤的话,就要遍历原始的List后重新生成新的List,至少需要两个List, 所以就想在不重新生成List的情况下,实现过滤功能.
首先声明一个过滤器接口 IObjectFilter
public interface IObjectFilter
{
//如果对象匹配成功,则返回true
boolean filter(Object object);
}
再继承ArrayList 实现 FilterArrayList :
public class FilterArrayList<T> extends ArrayList<T>
{
/**
*
*/
private static final long serialVersionUID = 1975316155027160540L;
private IObjectFilter mFilter;
private Integer[] mFilteredIndices; //过滤后的index,
public FilterArrayList(List<T> list)
{
super(list);
}
public FilterArrayList()
{
super();
}
public boolean add(T object)
{
//如果当前list处于过滤状态,则不允许添加新的对象
if(mFilter != null)
{
return false;
}
return super.add(object);
}
/*
* 在过滤状态下,要处理一系列插入删除动作, 有待完善
*/
@Override
public int size()
{
if(mFilteredIndices != null)
{
//此时,过滤后的index集合的大小就是整个List的大小
return mFilteredIndices.length;
}
else
{
return super.size();
}
}
public T get(int index)
{
if(mFilteredIndices != null)
{
//过滤状态下,转换过滤后对应的index
index = getFilteredIndex(index);
}
return super.get(index);
}
public void setFilter(IObjectFilter filter)
{
if(filter == null)
{
removeFilter();
}
else
{
mFilter = filter;
applyFilter();
}
}
private void applyFilter()
{
mFilteredIndices = null;
int size = super.size();
List<Integer> indices =new ArrayList<Integer>();
for(int i=0;i<size;i++)
{
//调用过滤接口
if(mFilter.filter(super.get(i)))
{
//如果返回true则保存此index
indices.add(i);
}
}
mFilteredIndices = new Integer[indices.size()];
indices.toArray(mFilteredIndices);
}
public void removeFilter()
{
mFilter = null;
mFilteredIndices = null;
}
private int getFilteredIndex(int index)
{
return mFilteredIndices[index];
}
}
使用方法:
//实体类
//实体类
class Employee
{
String empNo;
String briefCode;
String name;
...
};
List<Employee> employees = new List<Employee>();
employees.add(...);
employees.add(...);
employees.add(...);
.....
//下面是演示怎么使用过滤
String filterString; //获取界面上模糊匹配的字符串
//实例化过滤器
IObjectFilter filter = new IObjectFilter()
{
public boolean filter(Object object)
{
Employee emp = (Employee)object;
return (emp.empNo.indexOf(filterString) > -1
|| emp.name.indexOf(filterString) > -1
|| emp.briefCode.indexOf(filterString) > -1)
}
};
//对List设置过滤器
employees.setFilter(filter);
//OK, 现在List中就是我们需要过滤出来的对象了.
//取消过滤
employees.removeFilter();
或者
employees.setFilter(null);
这个方法其实没有改变原始数组的数据, 只是交换了一下index的位置, 避免了反复的重新生成List
还有待完善,