`
zhuqiang5138
  • 浏览: 31761 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

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/
分享到:
评论

相关推荐

    SAI_Split_APKs_Installer_v3.4.apk

    SAI(Split APKs安装程序)是一款应用程序,可让您像安装单个软件包一样安装多个APK。这对于安装作为应用程序捆绑包分发的应用程序很有用,因为Android没有提供从Google Play以外的其他来源安装它们的内置方法。 ...

    被删除的google android apks

    标题中的“被删除的google android apks”指的是Google在Android操作系统中提供的官方应用程序包,通常称为GApps(Google Applications)。这些APK文件是Google服务框架的一部分,包括Google Play商店、Google服务、...

    apks.zip 批量一键安装

    标题“apks.zip批量一键安装”指的是一个压缩文件,其中包含了一套工具,方便用户快速、批量地安装APK应用。这个工具集适用于Android设备,尤其是对于需要在多台设备上部署相同应用或者进行测试的用户,大大提升了...

    apks文件一键安装脚本

    适用于安卓的apks文件安装脚本,支持apk、apks、split apk安装、备份、恢复,只是安装的话,不需要root权限,但是备份与恢复需要root权限,里面有帮助说明,很简单的一个脚本。

    安卓版美顏相機_11.1.35.apks

    安卓版美顏相機_11.1.35.apks

    云货架上线apks-备份

    "云货架上线apks-备份"这一主题主要涉及到的是安卓应用在云端的管理和分发,以及备份策略。这里的关键知识点可以分为以下几个方面: 1. **云货架**:云货架是数字化零售的一种表现形式,它利用云计算技术将商品展示...

    SAI_Split_APKs_Installer_v4.2.apk

    SAI(拆分APK安装程序)是一款应用程序,可让您像安装一个软件包一样安装多个APK。这对于安装作为应用程序捆绑包分发的应用程序很有用,因为Android没有提供从Google Play以外的其他来源安装它们的内置方法。...

    Split APKs Installer SAI安装器v4.5捐赠版.zip

    标题中的“Split APKs Installer SAI安装器v4.5捐赠版”指的是一个特定版本的Android应用程序,用于处理和安装分割的APK文件。在Android系统中,特别是针对大型应用或游戏,为了减小单个APK文件的大小,开发者会将其...

    Apks from HUAWEI VNS-TL00

    Apks from HUAWEI VNS-TL00 - Android 键盘 (AOSP)_6.0-eng.jenkins.20180606.124225 - Microsoft Launcher_5.10.0.55723 - Shell_6.0-eng.jenkins.20180606.124225 - TalkBack_5.0.4 - 百度输入法华为版_5.5.6.163 ...

    batch_apks_tools.zip

    本文将详细介绍"batch_apks_tools.zip"这个压缩包提供的工具,它专门用于帮助开发者高效地进行APK的渠道分包和打包工作。 "batch_apks_tools"是一个自动化工具集,旨在简化APK的多渠道打包过程。传统的手动操作不仅...

    Apks from MI3TD

    【标题】"Apks from MI3TD" 指的是小米MI 3 TD手机的应用程序集合,这是一款专为小米MI 3 TD型号定制的安卓系统应用。这个压缩包包含了多个MIUI系统中的核心应用程序,让用户能够单独下载并安装这些应用。 【描述】...

    SAI v4.4 for Android 拆分APK安装程序,可安装 .apks 等格式的应用包.rar

    而“可安装 .apks 等格式的应用包”表明此版本的SAI v4.4支持安装以.apks为扩展名的文件。.apks格式是Android系统用于分发多APK应用的打包格式,通常用于Play Store的动态分发或侧载安装。 标签“SAIv4.4forAnd”是...

    apks for google play store installation for android

    标题和描述提到的"apks for google play store installation for android"指的是为安卓设备安装Google Play商店所需的APK文件。APK是Android应用程序的包文件格式,相当于iOS中的IPA文件。这里我们将详细讨论如何...

    傻瓜式一键谷歌aab转apks

    里面包含aab转换位apks所需的所有文件,并将其使用方法完整的写在说明txt中,小白也可以直接使用。 由Google提供的命令行工具,用于处理Android App Bundles。 将其封装到一个文件夹下,方便使用,适用与检测aab包体...

    aabs自动生成apks,并安装到模拟器脚本工具

    标题中的"aabs自动生成apks,并安装到模拟器脚本工具"是一个自动化流程,用于处理Android App Bundle(aab)格式的应用程序,并将其部署到Android模拟器上进行测试或调试。在Android开发中,aab是一种优化的发布格式...

    opencv-3.2.0-android-sdk-apks(仅包含了apk)

    在这个特定的压缩包"opencv-3.2.0-android-sdk-apks.7z"中,我们只找到了针对Android平台的SDK的APK文件。 OpenCV for Android SDK是为Android开发者设计的,让他们能够轻松地在Android设备上集成计算机视觉功能。...

    J2ME Loader_apks.apk

    J2ME Loader_apks.apk

    Geekbench 5_5.4.4.apks

    Geekbench 5_5.4.4.apks

    利用BundleTool从aab包获取apk安装大小以及安装apk到手机

    java -jar bundletool.jar install-apks --apks=path/to/output.apks --adb=path/to/adb ``` 这里的`adb`是指Android Debug Bridge,通常在Android SDK的platform-tools目录下。 3. `BundleTool`会自动识别连接...

    浮生_1.1.13_apks.apk

    浮生_1.1.13_apks.apk

Global site tag (gtag.js) - Google Analytics