apks

CursorAdapter如何实现关键字过滤 

2010-12-10 13:13:14|  分类: Android基础 |字号 订阅
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方法来进行数据库的过滤查询

如何使用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方法来进行数据库的过滤查询
/***
* AndroidManifest.xml
*
<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>


/***
* AutoMultipleContacts.java
*

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Contacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.Filterable;
import android.widget.MultiAutoCompleteTextView;
import android.widget.TextView;

public class AutoMultipleContacts extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.multipleselect);

Cursor peopleCursor = getContentResolver().query(Contacts.People.CONTENT_URI, PEOPLE_PROJECTION, null, null, Contacts.People.DEFAULT_SORT_ORDER);
ContactListAdapter contactadapter = new ContactListAdapter(this,peopleCursor);

MultiAutoCompleteTextView textView = (MultiAutoCompleteTextView) findViewById(R.id.contacts);
textView.setAdapter(contactadapter);
textView.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
}


public static class ContactListAdapter extends CursorAdapter implements Filterable {
public ContactListAdapter(Context context, Cursor c) {
super(context, c);
mContent = context.getContentResolver();
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
final TextView view = (TextView) inflater.inflate(
android.R.layout.simple_dropdown_item_1line, parent, false);
view.setText(cursor.getString(5));
return view;
}

@Override
public void bindView(View view, Context context, Cursor cursor) {
((TextView) view).setText(cursor.getString(5));
}

@Override
public String convertToString(Cursor cursor) {
return cursor.getString(5);
}

@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
if (getFilterQueryProvider() != null) {
return getFilterQueryProvider().runQuery(constraint);
}

StringBuilder buffer = null;
String[] args = null;
if (constraint != null) {
buffer = new StringBuilder();
buffer.append(\"UPPER(\");
buffer.append(Contacts.ContactMethods.NAME);
buffer.append(\") GLOB ?\");
args = new String[] { constraint.toString().toUpperCase() + \"*\" };
}

return mContent.query(Contacts.People.CONTENT_URI, PEOPLE_PROJECTION,
buffer == null ? null : buffer.toString(), args,
Contacts.People.DEFAULT_SORT_ORDER);
}

private ContentResolver mContent;
}

private static final String[] PEOPLE_PROJECTION = new String[] {
Contacts.People._ID,
Contacts.People.PRIMARY_PHONE_ID,
Contacts.People.TYPE,
Contacts.People.NUMBER,
Contacts.People.LABEL,
Contacts.People.NAME,
};

}





/***
* res/layout/multipleselect.xml
*

<?xml version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
android:orientation=\"vertical\"
android:layout_width=\"fill_parent\"
android:layout_height=\"fill_parent\"
>

<LinearLayout
android:layout_width=\"fill_parent\"
android:layout_height=\"wrap_content\"
android:gravity=\"center_vertical\">

<MultiAutoCompleteTextView
android:id=\"@+id/contacts\"
android:textSize=\"18sp\"
android:layout_margin=\"8px\"
android:layout_width=\"0px\"
android:layout_height=\"wrap_content\"
android:layout_weight=\"1\" />

</LinearLayout>
</LinearLayout>

关于这方面的知识,还可以参见下面两篇文章:
http://blog.csdn.net/dragondog/article/details/6234052


http://hubingforever.blog.163.com/blog/static/1710405792010111011314506/

你可能感兴趣的:(apks)