Android搜索过滤
一、简介一般来说,我们可以使用以下几种方式实现搜索:1)暴力搜索——直接使用数据库提供的功能,每次都从数据库中读取搜索的结果,存进一个数据结构用于Adapter显示,调用notifyDataSetChanged()刷新数据;2)利用filter进行搜索。这块涉及到Filterable接口。推荐文章:Android实现Filterable通过输入文本框实现联系人自动筛选。有两
一般来说,我们可以使用以下几种方式实现搜索:
1)暴力搜索——直接使用数据库提供的功能,每次都从数据库中读取搜索的结果,存进一个数据结构用于Adapter显示,调用notifyDataSetChanged()刷新数据;
2)利用filter进行搜索。这块涉及到Filterable接口。推荐文章:Android实现Filterable通过输入文本框实现联系人自动筛选。有两点值得注意:a)Android原生组件AutoCompleteTextview就是使用该方法实现的;b)这个方法本质上还是调用notifyDataSetChanged()方法,并且还是要自己去实现搜索部分,只是整个方法看上去比较优雅,而且不用再去搜索数据库,最重要的一点是这个时候搜索过程被自动移到另外一个线程之中,搜索完毕之后才会刷新UI;
CursorFilter类就是Filter类的继承。CursorFilter在performFiltering中并没有直接进行数据的过滤,而是加入了CursorFilterClient成员,将过滤的操作转让给了CursorFilterClient,实际上CursorAdpater就是继承了CursorFilterClient接口,也就是说过滤操作实际上是在CursorAdapter中执行的。
CursorAdapter实现Filterable接口实现了下面的方法
public Filter getFilter() {
if (mCursorFilter == null) {
mCursorFilter = new CursorFilter(this);
}
return mCursorFilter;
}
看一下CursorFilter的实现,实现Filter的两个抽象方法
class CursorFilter extends Filter {
CursorFilterClient mClient;
CursorFilter(CursorFilterClient client) {
mClient = client;
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
Cursor cursor = mClient.runQueryOnBackgroundThread(constraint);
FilterResults results = new FilterResults();
if (cursor != null) {
results.count = cursor.getCount();
results.values = cursor;
} else {
results.count = 0;
results.values = null;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
Cursor oldCursor = mClient.getCursor();
if (results.values != null && results.values != oldCursor) {
mClient.changeCursor((Cursor) results.values);
}
}
查询工作交给了CursorFilterClient这个类,而CursorAdapter实现了这个接口,所以
Cursor cursor = mClient.runQueryOnBackgroundThread(constraint);
这个方法是在CursorAdapter中实现的,我们看下
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
if (mFilterQueryProvider != null) {
return mFilterQueryProvider.runQuery(constraint);
}
return mCursor;
}
其中的mFilterQueryProvider需要我设置一下
public void setFilterQueryProvider(FilterQueryProvider filterQueryProvider) {
mFilterQueryProvider = filterQueryProvider;
}
看一下FilterQueryProvider这个接口,只有一个抽象方法
public interface FilterQueryProvider {
Cursor runQuery(CharSequence constraint);
}
所以我们需要在外面继承这个接口实现它,并且实现runQuery方法中的查询搜索。
然后通过CursorAdapter的setFilterQueryProvider方法设置,之后整个机制完全串联起来,在外调用adapter.getFilter().filter(et_filter.getText().toString()); 即可启动整个过滤机制。
整个机制实际上是用异步查询然后显示的流程,主要的流程处理在Filter的类中。下篇文章分析下Filter的具体实现
更多推荐
所有评论(0)