Android基础教程:CursorAdapter如何实现关键字过滤

Android.widget.CursorAdapter
它首先实现了两个接口Filterable,CursorFilter.CursorFilterClient
其中Filterable接口定义了getFilter()这个接口。
CursorFilterClient定义如下接口
        CharSequence convertToString(Cursor cursor);
        Cursor runQueryOnBackgroundThread(CharSequence constraint);
        Cursor getCursor();
        void changeCursor(Cursor cursor);

注意:CursorFilter.CursorFilterClient是非public的,所以只有文档中看不到它,在源码中才能看到它。
CursorAdapter.java文件如下      
package android.widget;
-----------------------------------省略---------------------------------
public abstract class CursorAdapter extends BaseAdapter implements Filterable,
        CursorFilter.CursorFilterClient {
    /**
     * This field should be made private, so it is hidden from the SDK.
     * {@hide}
     */

    protected boolean mDataValid;
    /**
     * This field should be made private, so it is hidden from the SDK.
     * {@hide}
     */

    protected boolean mAutoRequery;
    /**
     * This field should be made private, so it is hidden from the SDK.
     * {@hide}
     */

    protected Cursor mCursor;
-----------------------------------省略---------------------------------
    protected CursorFilter mCursorFilter;
    /**
     * This field should be made private, so it is hidden from the SDK.
     * {@hide}
     */

    protected FilterQueryProvider mFilterQueryProvider;
-----------------------------------省略---------------------------------
    public Cursor getCursor() {
        return mCursor;
    }
-----------------------------------省略---------------------------------       
    public void changeCursor(Cursor cursor) {
-----------------------------------省略---------------------------------
    }
-----------------------------------省略---------------------------------
    public CharSequence convertToString(Cursor cursor) {
        return cursor == null ? "" : cursor.toString();
    }
-----------------------------------省略---------------------------------
    public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
        if (mFilterQueryProvider != null) {
            return mFilterQueryProvider.runQuery(constraint);
        }
        return mCursor;
    }
    public Filter getFilter() {
        if (mCursorFilter == null) {
            mCursorFilter = new CursorFilter(this);
        }
        return mCursorFilter;
    }
-----------------------------------省略---------------------------------
    public FilterQueryProvider getFilterQueryProvider() {
        return mFilterQueryProvider;
    }
-----------------------------------省略---------------------------------
    public void setFilterQueryProvider(FilterQueryProvider filterQueryProvider) {
        mFilterQueryProvider = filterQueryProvider;
    }
-----------------------------------省略---------------------------------
}
CursorFilter文件如下:
package android.widget;
import android.database.Cursor;
class CursorFilter extends Filter {  
    CursorFilterClient mClient;
    interface CursorFilterClient {
        CharSequence convertToString(Cursor cursor);
        Cursor runQueryOnBackgroundThread(CharSequence constraint);
        Cursor getCursor();
        void changeCursor(Cursor cursor);
    }
    CursorFilter(CursorFilterClient client) {
        mClient = client;
    }  
    @Override
    public CharSequence convertResultToString(Object resultValue) {
        return mClient.convertToString((Cursor) resultValue);
    }
    @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);
        }
    }
}
关于Filter的更多内容参见《关键字过滤器Filter》。
如何使用Filter呢?
调用CursorAdapter的getFilter方法得到一个Filter,调用它的filter (CharSequence constraint)方法。其中constraint就是关键字。
注意1:如果不给CursorAdapter设置FilterQueryProvider(通过setFilterQueryProvider方法),
那么就需要重载Cursor runQueryOnBackgroundThread(CharSequence constraint)来实现对数据库的过滤查询。
当然FilterQueryProvider其实就是在它唯一的方法public abstract Cursor runQuery (CharSequence constraint)里面实现对数据库的过滤查询。
参考源代码可以知道如果提供了FilterQueryProvider,那么CursorAdapter就是在runQueryOnBackgroundThread方法中直接调用FilterQueryProvider的runQuery方法来进行数据库的过滤查询

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyxdfs.html